Manipolazione file di testo

di il
5 risposte

Manipolazione file di testo

Premessa: ho già risolto da solo (in realtà googlando per ore ), ma la mia soluzione (come da account sono veramente "poco pratico" ) mi sembra alquanto macchinosa, per cui la mia richiesta è se esiste qualche strada meno tortuosa per arrivare all' obbiettivo.
Problema: ho dei file generati in automatico che hanno una struttura tipo questa:
SetMachiningParameters ("EF", 1, 10, 16777216, false);

CreateFinishedWorkpieceBox ("pezzo", 500, 400, 20);
CreateRawWorkpiece ("pezzo", 0, 0, 0, 0, 0, 0);
SetWorkpieceSetupPosition (0, 0, 0, 0);
SetWorkPieceLabel(120, 90, 90);

//FRESA 2 TAGLIENTI Estrusione

//Origine parte 1
SelectWorkplane ("Top");

//Estrusione
ResetPneumaticHood ();
ResetAuxiliaryHood ();
ResetDustpan ();
SetJerk (3);
CreatePolyline ("OP1_1 - Estrusione_Polyline", 250, 0);
AddSegmentToPolyline (500, 0);
AddSegmentToPolyline (500, 327.5);
AddSegmentToPolyline (433.81, 327.5);
AddSegmentToPolyline (433.81, 400);
AddSegmentToPolyline (69.68, 400);
AddSegmentToPolyline (69.68, 327.5);
AddSegmentToPolyline (0, 327.5);
AddSegmentToPolyline (0, 0);
AddSegmentToPolyline (250, 0);
CreateRoughFinish ("OP1_1 - Estrusione",-27,"Estrusione",TypeOfProcess.GeneralRouting, "Estrusione", "0", 0, -1, 9999, 30, 0);

//FRESA 2 TAGLIENTI NEST1228

//TASCA SGROSSATA
SetJerk (3);
CreatePolyline ("OP2_1 - TASCA SGROSSATA_Polyline", 274.31, 88);
AddSegmentToPolyline (274.31, 88);
SetAttribute ("DEPTH", -40.01);
CreateRoughFinish ("OP2_1 - TASCA SGROSSATA",-40,"TASCA SGROSSATA",TypeOfProcess.GeneralRouting, "NEST1228", "0", 0, -1, 18000, 10, 0);
CreateToolpath ("OP2_1 - TASCA SGROSSATA_ToolPath", 274.31, 88, 40);
AddSegmentToToolpath (274.31, 88, -3);
SetToolpathAttribute("FEED", 7.5);
AddSegmentToToolpath (274.31, 86, -3);
SetToolpathAttribute("FEED", 10);
AddSegmentToToolpath (253.5, 86, -3);
AddSegmentToToolpath (253.5, 126.5, -3);
AddSegmentToToolpath (399, 126.5, -3);
AddSegmentToToolpath (399, 86, -3);
AddSegmentToToolpath (274.31, 86, -3);
AddArc2PointRadiusToToolpath (264.88, 90.25, -3, 12.6, true, false);
AddArc2PointRadiusToToolpath (261.81, 100.13, -3, 12.6, true, false);
AddArc2PointRadiusToToolpath (261.9, 101.66, -3, 12.6, false, false);
AddSegmentToToolpath (261.9, 118.1, -3);
AddSegmentToToolpath (390.6, 118.1, -3);
AddSegmentToToolpath (390.6, 94.4, -3);
AddSegmentToToolpath (261.9, 94.4, -3);
AddSegmentToToolpath (261.9, 101.66, -3);
AddArc2PointRadiusToToolpath (265.01, 108.18, -3, 8.4, true, false);
AddArc2PointRadiusToToolpath (272.02, 109.88, -3, 8.4, true, false);
AddArc2PointRadiusToToolpath (273.75, 109.7, -3, 8.4, false, false);
AddSegmentToToolpath (382.2, 109.7, -3);
AddSegmentToToolpath (382.2, 102.8, -3);
AddSegmentToToolpath (270.3, 102.8, -3);
AddSegmentToToolpath (270.3, 102.8, 20);
SetToolpathAttribute("FEED", 20);

//PUNTA A FONDO PIANO PL04.2DX

SetJerk (0);
CreateDrill ("OP3_1", 114.68, 260, 20, 4.2, "", TypeOfProcess.Drilling, "-1", "-1", 0, 6000, 4, "P", 0, 20);

//PUNTA A FONDO PIANO PC08SX

SetJerk (0);
CreateDrill ("OP4_1", 142.5, 162.5, 10, 8, "", TypeOfProcess.Drilling, "-1", "-1", 0, 6000, 4, "P", 0, 20);
ResetJerk ();
io devo:
1_estrapolare dalla riga 3 (contando anche le righe vuote) dalla parte "("pezzo", 500, 400, 20)" questa stringa "("pezzo", 20)" Ovviamente la stringa è diversa da file a file
2_Individuare il blocco di righe da "//Estrusione" a "CreateRoughFinish ("OP1_1 - Estrusione",-27,..." (il contenuto varia da file a file, ma apertura e chiusura sono sempre uguali)
3_Sostituire l'ultima riga di tale blocco con "CreateFinishedWorkpieceFromExtrusion" + la stringa estrapolata dalla riga 3 "("pezzo", 20)"
4_modificare il file con una stringa composta da:
a_le prime due righe (contando anche quella vuota)
b_il blocco individuato e modificato in precedenza
c_le righe che ci sono dalla 5 ad inizio blocco individuato ( le righe 3 e 4 scompaiono)
d_tutto quello che c'è dopo il blocco individuato

Ho usato la funzione "Open for input" creando un array in cui ho inserito le righe
Manovrando vari cicli ho sistemato l'array come mi serviva
Con la funzione "Open for output" ho modificato il file.
Manca tutta la parte da gestire con "Open Dialog Box" perchè questa operazione la dovrò fare su tutti i file contenuti in una cartella specificata dall' utente.
Questo è il codice:
Private Sub Comando0_Click()
Dim strStart As String 'stringa da cui parte il blocco da spostare
Dim strEnd As String ' stringa in cui finisce il blocco da spostare
Dim strCopia As String ' stringa da spostare
Dim intStart 'numero riga da cui parte il blocco da spostare
Dim intStop 'numero riga in cui finisce il blocco da spostare
Dim intSpostamento As Integer 'intStop-intStart
Dim strNuovoTesto 'concateno tutte le stringe che formano l'array

Dim NumeroRiga As Integer
Dim strLettura As String 'creata solo per poter contare le righe del file e dimensionare l'array (non so come fare diversamente)
Dim strTesto() As String
Dim intContatore As Integer
'conto quante righe ci sono per dimensionare l'array
Open "C:\PEZZO - Copia.xcs" For Input As #1
NumeroRiga = 0
Do Until EOF(1)
NumeroRiga = NumeroRiga + 1
Line Input #1, strLettura
Loop
Close #1
ReDim strTesto(NumeroRiga)
'riapro per riempire l'array
Open "C:\PEZZO - Copia.xcs" For Input As #1
NumeroRiga = 0
Do Until EOF(1)
NumeroRiga = NumeroRiga + 1
Line Input #1, strTesto(NumeroRiga)
Loop
Close #1
'cerco la riga iniziale "\\Estrusione"
strStart = "//Estrusione"
For intContatore = 1 To NumeroRiga
If InStr(1, strTesto(intContatore), strStart) Then
intStart = intContatore
Exit For
End If
Next
'cerco la riga finale
strEnd = "CreateRoughFinish"
For intContatore = intStart To NumeroRiga
If InStr(1, strTesto(intContatore), strEnd) Then
intStop = intContatore
Exit For
End If
Next
'isolo il nome del pezzo
'A-misuro lunghezza riga 3 "CreateFinishedWorkpieceBox ("xxx", xxx, xxx, xxx)e tolgo la parte prima delle parentesi
Dim intRiga3 As String
Dim strRiga3Sx As String
Dim strRiga3Dx As String
Dim intPrimaVirgola
Dim intSecondaVirgola
Dim intTerzaVirgola
intRiga3 = Len(strTesto(3))
strTesto(3) = Right(strTesto(3), intRiga3 - 27)
'B-cerco le virgole per togliere lunghezza e larghezza
intPrimaVirgola = InStr(1, strTesto(3), ",")
intSecondaVirgola = InStr(intPrimaVirgola + 1, strTesto(3), ",")
intTerzaVirgola = InStr(intSecondaVirgola + 1, strTesto(3), ",")
'C-separo sinistra e destra per creare la stringa finale
intRiga3 = Len(strTesto(3))
strRiga3Sx = Left(strTesto(3), intPrimaVirgola - 1)
strRiga3Dx = Right(strTesto(3), intRiga3 - intTerzaVirgola + 1)
strTesto(intStop) = "CreateFinishedWorkpieceFromExtrusion" & strRiga3Sx & strRiga3Dx


'creo la stringa per il nuovo testo con il blocco spostato
'prime righe fisse
strNuovoTesto = strTesto(1) & vbCrLf
strNuovoTesto = strNuovoTesto & strTesto(2) & vbCrLf
'blocco di definizione pezzo
For intContatore = intStart To intStop
strNuovoTesto = strNuovoTesto & vbCrLf & strTesto(intContatore)
Next
'inserisco uno spazio per chiarezza
strNuovoTesto = strNuovoTesto & vbCrLf
'tutto quello che c'era da 5 a intStart-1 (le righe 3 e 4 vengono sostituite dal blocco)
For intContatore = 5 To intStart - 1
strNuovoTesto = strNuovoTesto & vbCrLf & strTesto(intContatore)
Next
'tutto quello che c'era dopo intStop
For intContatore = intStop + 1 To NumeroRiga
strNuovoTesto = strNuovoTesto & vbCrLf & strTesto(intContatore)
Next

'scrivo il nuovo file
Open "C:\PEZZO - Copia.xcs" For Output As #1
Print #1, strNuovoTesto
Close #1
End Sub
Grazie per la collaborazione ,
Paolo

5 Risposte

  • Re: Manipolazione file di testo

    Siccome quello è un file di configurazione... io lo scorrerei tutto e salverei i dati in una Collection di Classi che a sua volta contiene una Collection di Valori...

    Nella Collection di Classi salvi la Classe con Key=[NomeSetting]=[CreateFinishedWorkpieceBox] in questo modo sarà semplice la ricerca per Nome, nella Classe quindi implementi una Public Property [Name] e gestisci gli ADD dei valori nella Collection di valori, quindi con una Public Property rendi leggibile la collection di valori.

    Sembra complicato sono poche righe di codice, sicuramente meno di quello che hai fatto...!

    P.S. per spezzare i Valori, usa SPLIT ed ottieni un'array ciclabile, se generi la Classe invece prevedi di passarlo così com'è e sviluppi nella classe l'interrogazione dell'indice Iesimo...
  • Re: Manipolazione file di testo

    Grazie Alex. Ovviamente non ho idea di cosa stiamo le classi e tanto meno di come ci si lavori
    Qualche link dove se ne parla?
  • Re: Manipolazione file di testo

    Argomento non banale, e non da improvvisare...!
    Avevo scritto diversi tutorial sulle classi ma il sito è stato chiuso... non saprei dove orientarti in rete c'è molto ma l'argomento è da costruire capiti i concetti... e con le classi sono più fumosi o meglio meno concreti da capire.

    Non so se consigliartelo a questo punto.

    In un Modulo crei una Collection chiamata cSettings ed una funzione per Aggiungere ogni Property di Setting
    Poi Crei un modulo di Classe chiamato cSetting che gestisce il Setting con i suoi valori.

    Ora banalizzo e semplifico.

    Questa funzione consente ogni riga del file che cicli di passare a questa funzione il Nome del Setting e la lista valori.
    
    Public cSettings As Collection
    
    Public Sub AddSetting(pSetting as String, pValues as Variant)
        If cSettings Is Nothing Then Set cSettings = New Collection
        Dim c As cSetting
        Set c=new cSetting
        cSetting.Name=pSetting
        cSetting.Values=pValues 
        cSettings.Add cSetting,pSetting
    End Sub 
    Questa è la Classe nella quale memorizzi l'ISTANZA del Setting singolo...
    
    Option Compare Database
    Option Explicit
    
    Private mValues     As Collection
    Private mName	     As String
    
    Private Sub Class_Initialize()
        Set mValues = New Collection
    End Sub
    Private Sub Class_Terminate()
        Set mValues=Nothing
    End Sub
    
    Public Property Let Name(pName As String)
        mName= pName 
    End Property
    Public Property Get Name() As String
        Name= mName 
    End Property
    
    Public Property Get Values() As Collection
        Set Values= mValues     
    End Property
    
    Function AddValue(pValue As Variant) As Boolean
        On Error Resume Next
        mValues .Add pValue, cstr(pValue)
    End Function
    Fai attenzione ai Plurali, indicano la Collection di dati [cSettings] mentre il Singolare la singola istanza di Classe [cSetting].

    Immagino che questo ti crei più dubbi che certezze... quindi se vorrai approfondire... vedrai, siamo quì.
  • Re: Manipolazione file di testo

    Immagino che questo ti crei più dubbi che certezze..
    Esatto
    Ma in particolare.... Se non ho capito male, la classe ti permette di creare oggetti trattabili come gli altri oggetti di VBA, con proprietà, metodi e via dicendo, tutto gestito dal programmatore,giusto?
    Ora, siccome io ho, come scritto nel post di apertura:
    -5 righe sempre uguali, di cui devo eliminare la 4 e sostituire la 3 leggendone però prima una parte che mi interessa,
    -Un blocco di righe, potenzialmente sempre diverso e sempre in posizioni diverse, ma che inizia e finisce allo stesso modo; questo blocco, con l'ultima riga modificata, lo devo sostituire alla riga 3
    Tutto il resto, che deve rimanere com'è.
    Ecco, ribadito questo, mi sfugge l'utilità della classe per il caso specifico.... Ma probabilmente ho capito troppo poco del tuo post
  • Re: Manipolazione file di testo

    È una questione di compattezza e fruibilità.

    Se devi fruire di quei settings nel processo di lavoro... avere una collection di classi velocizza la ricerca e la fruibilità dei dati.
    Ci sono anche gli Array ma per fare ricerche serve scorrere tutto ed in vari casi di questo tipo sono più lenti.

    Se nel tuo caso leggi e modifichi solo 1 volta ma non fruisci dei dati, allora la classe non serve...

    Vedi tu.
Devi accedere o registrarti per scrivere nel forum
5 risposte