Modificare contenuto di più file di testo

di il
8 risposte

Modificare contenuto di più file di testo

Buongiorno a tutti e auguri alle mamme, se ce ne sono di collegate
Ho una situazione di questo genere:
Una cartella "NomeCartella" che contiene una serie di file ("caio", "tizio" "sempronio") che iniziano tutti con questa struttura:
CreateFinishedWorkpieceBox ("1 CB Basamento", 1175, 1175, 25);
CreateRawWorkpiece ("1 CB Basamento", 0, 0, 0, 0, 0, 0);
Ho bisogno di ciclare tutti i file all' interno della cartella ed aggiungere il nome della cartella ai workpiece, in modo che diventi:
CreateFinishedWorkpieceBox ("NomeCartella - 1 CB Basamento", 1175, 1175, 25);
CreateRawWorkpiece ("NomeCartella - 1 CB Basamento", 0, 0, 0, 0, 0, 0);
Per selezionare la cartella che contiene i file userei:
Application.FileDialog(msoFileDialogFolderPicker)
e per modificare il file :
OPEN(pathname For mode [Access access] [lock] As [#] filenumber [Len = reclength])
ma non riesco a trovare un modo per far ciclare e modificare da access in automatico tutti i file della cartella....
Qualche idea?
P.S. ho pensato ad Access perchè l'unico linguaggio di programmazione che conosco un pochino è il VBA. Se ci sono altri programmi più adatti per fare questa modifica mi va benissimo lo stesso
Grazie in anticipo

8 Risposte

  • Re: Modificare contenuto di più file di testo

    PocoPratico ha scritto:


    Una cartella "NomeCartella" che contiene una serie di file ("caio", "tizio" "sempronio") che iniziano tutti con questa struttura:
    CreateFinishedWorkpieceBox ("1 CB Basamento", 1175, 1175, 25);
    CreateRawWorkpiece ("1 CB Basamento", 0, 0, 0, 0, 0, 0);
    Scusa...io non ci arrivo:
    NomeCartella è il nome di una cartella: OK
    Caio, Tizio, Sempronio sono file: che estensione hanno?
    Cosa sono i file "workpiece"? Non li conosco.
  • Re: Modificare contenuto di più file di testo

    OsvaldoLaviosa ha scritto:


    ...
    Caio, Tizio, Sempronio sono file: che estensione hanno?
    Cosa sono i file "workpiece"? Non li conosco.
    Si tratta di modificare file di testo. Non è un lavoro tipicamente da Access ma PocoPratico lo usa perché conosce VBA. Anch'io ho fatto qualche lavoretto del genere sfruttando di Access praticamente solo la parte grafica.

    PocoPratico ha scritto:


    ma non riesco a trovare un modo per far ciclare e modificare da access in automatico tutti i file della cartella....
    La funzione Dir. Ne abbiamo parlato di recente in questo thread (pure in altri, troppi per i miei gusti ma non c'entri tu)
    https://www.iprogrammatori.it/forum-programmazione/access/spostare-file-con-parte-nome-preso-campo-una-directory-altra-t49590.html
    Puoi servirti delle funzioni native di vba che dovrebbero bastare, oppure in caso di necessità di FileSystemObject (anche questo presente nel thread citato)
    Devi modificare tutte le righe del file o solo le prime 2?
  • Re: Modificare contenuto di più file di testo

    Grazie, Philcattivocarattere.
    Devo modificare solo le stringhe tra apici delle prime due righe.
    Ho dato un' occhiata al link che mi hai consigliato e pare che faccia proprio al caso mio. Che poi io riesca effettivamente ad usare la funzione DIR in modo efficace è poi ancora un altro discorso .
    Ma ci proverò e posterò eventuale soluzione trovata
    buona serata
  • Re: Modificare contenuto di più file di testo

    PocoPratico ha scritto:


    Grazie, Philcattivocarattere.
    Devo modificare solo le stringhe tra apici delle prime due righe.
    Ho dato un' occhiata al link che mi hai consigliato e pare che faccia proprio al caso mio. Che poi io riesca effettivamente ad usare la funzione DIR in modo efficace è poi ancora un altro discorso .
    Ma ci proverò e posterò eventuale soluzione trovata
    buona serata
    Visto che quel thread è stato un po' tribolato estrapolo la parte che può interessarti che riguarda l'uso di Dir
    Dim strFileName As String, strFolder As String, strFileSpec As String
    strFolder = "C:\temp\"
    strFileSpec = strFolder & "*.*"
    strFileName = Dir(strFileSpec)
    Do While Len(strFileName) > 0
        'TODO: replace Debug.Print by the process you want to do on the file
        Debug.Print strFileName
        strFileName = Dir
    Loop
    All'interno del ciclo Do ... Loop metti il codice di modifica del file.
    Considerando che devi modificare solo le prime due righe di ogni file di primo acchito fare una copia del file originale, aprirei la copia appena creata, modificando appunto solo le prime due righe. Sai come si legge una riga alla volta?
    Questo porzione di codice trovato qui https://www.automateexcel.com/vba/read-text-file-line-by-line/ te ne dà una dimostrazione, ma fai attenzione che qui il file è aperto per la sola lettura.
    
    Dim strFile As String, strLine As String
    strFile = "C:\Test\TestFile.txt"
    Open strFile For Input As #1
    Do Until EOF(1)
       Line Input #1, strLine
       ...
    Loop
    Close #1
    
    (nella pagina trovi molto altro, anche l'uso di FSO, non ti curare del fatto che vengano scritte le righe poi in un foglio di excel).
    Nel tuo caso devi limitarti alle prime due righe, quindi non è utile verificare l'EOF, se non per evitare l'errore di andare a cercare una riga in un file che non ne contiene o una seconda riga in un file che ne ha una sola.
    In pratica ti basta impostare una variabile che ripete il ciclo solo 2 volte, puoi farlo con un For ... Next.
    
    Dim i as Integer
    For i = 1 To 2
       Line Input #1, strLine
       ...
    Next
    Ci potrebbe stare un Replace abbastanza semplice ma fa' attenzione al fatto che devi inserire all'interno della stringa da ricercare e in quella sostitutiva il carattere "doppioapice" che in VBA è anche il delimitatore del testo all'interno del codice.
    Per capirci, questa istruzione non funzionerà
    Replace(tuariga, "CreateFinishedWorkpieceBox ("", "CreateFinishedWorkpieceBox ("NomeCartella - ")
    perché non c'è corrispondenza tra i doppiapici di apertura e chiusura.
    In questi casi si deve raddoppiare il doppioapice o usare Chr$(34). Ti suggerisco di usare due variabili ad hoc per il secondo e terzo parametro di Replace, in modo che sia più facile anche farne il debug, per vedere se tutto viene scritto come vorresti.
  • Re: Modificare contenuto di più file di testo

    Urca!!!! Sono impressionato dalla tua competenza e disponibilità.
    Veramente!!!!
  • Re: Modificare contenuto di più file di testo

    Rimanendo legato al thread incontro il seguente problema:
    eseguo un loop che, leggendo dati da una tabella con (tra gli altri) i campi "modulo" e "nome", crea dei file "nome.xcs" nella cartella "modulo". Quando finisco i "nome" con lo stesso "modulo", prima di passare al "modulo" successivo lancio un file batch che converte i file da .Xcs a .Pgmx
    Ad ogni loop il file batch viene modificato da codice per convertire tutti i file contenuti nella cartella "modulo"
    Se eseguo il codice passo passo, tutto funziona perfettamente, se invece lo lancio da access il file batch converte solo i file contenuti nell' ultima cartella creata .
    Immagino che dovrei fermare l'esecuzione del ciclo per dare il tempo al batch di fare il suo lavoro sui file di una cartella prima di chiedergli di passare alla successiva, ma non ho idea di come fare .
    Ho pensato di copiare il batch "modello" nella cartella "modulo" prima di lanciarlo, ma mi restituisce "errore 70 " (autorizzazione negata), e il problema non è che il file è in rete, perchè lo fa anche se lo sposto "a mano" in locale.
    Qualche idea?
    P.S. questo è il codice:
     Private Sub cmdCreaPgmx_Click()
    'se sono in modalità modifica, salvo il file
    If Me.Dirty Then
       DoCmd.DoMenuItem acFormBar, acRecordsMenu, acSaveRecord, , acMenuVer70
    End If
    'controllo se c'è il link alla cartella nella commessa
        If IsNull(DLookup("linkCartella", "tblCommesse", "Idcommessa=" & Forms!frmCommessa!IDCommessa)) Then
            MsgBox ("Non c'è il percorso della Commessa" & vbCrLf & _
                    "Non so dove salvare")
            Exit Sub
        ElseIf DLookup("linkCartella", "tblCommesse", "Idcommessa=" & Forms!frmCommessa!IDCommessa) = "" Then
            MsgBox ("Non c'è il percorso della Commessa" & vbCrLf & _
                    "Non so dove salvare")
            Exit Sub
        End If
        
    
    Dim strOrigine As String 'Percorso del file modello.xcs
    Dim strDestinazione As String 'Percorso di destinazione degli xcs creati
    Dim strFileUscita As String 'Percorso completo del file di uscita
    Dim strXCS As String 'Stringa da scrivere nel file .xcs
    Dim strPezzo As String 'Nome del pezzo e del file
    Dim strSqlMateriali As String 'elenco dei materiali della commessa
    Dim strSqlPezzi As String 'elenco dei pezzi della commessa
    Dim dbs As Database
    Dim rstMateriali As Recordset
    Dim rstPezzi As Recordset
    Dim strBatch As String 'riempie il file batch
    Dim strLung As String
    Dim strLarg As String
    Dim strSp As String
    
    strSqlMateriali = "SELECT tblCommessePannelli.IdCommessa, tblArticoli.IDArticolo, tblArticoli.Articolo, tblCommessePannelli.Sp, tblCommessePannelli.Pgmx" & _
                     " FROM tblArticoli RIGHT JOIN tblCommessePannelli ON tblArticoli.IDArticolo = tblCommessePannelli.IdArticolo" & _
                     " WHERE tblCommessePannelli.IdCommessa=" & Forms!frmCommessa!IDCommessa & " AND tblCommessePannelli.Pgmx=True"
    
    strSqlPezzi = "SELECT tblCommessePezzi.IdCommessa, tblArticoli.Articolo, tblCommessePezzi.Sp, cod &'_'& [modulo] & '-' & [nome] AS Pezzo, tblCommessePezzi.Lung, tblCommessePezzi.Larg, tblCommessePezzi.Qtà" & _
                  " FROM tblCommessePezzi LEFT JOIN tblArticoli ON tblCommessePezzi.IdArticolo = tblArticoli.IDArticolo" & _
                  " WHERE tblCommessePezzi.IdCommessa=" & Forms!frmCommessa!IDCommessa
    
    
    
    Set dbs = CurrentDb
    Set rstMateriali = dbs.OpenRecordset(strSqlMateriali)
    Set rstPezzi = dbs.OpenRecordset(strSqlPezzi)
    strOrigine = "H:\RiservatiAccess\Modello.XCS"
    strDestinazione = Me!CartellaOutput & "\PGMX"
    
    'controlla se c'è già la cartella di output di primo livello, se no la crea
                Dim fdObj As Object
                Set fdObj = CreateObject("Scripting.FileSystemObject")
                If fdObj.FolderExists(strDestinazione) Then 'se c'è già non fa niente
                Else
                    fdObj.CreateFolder (strDestinazione)
                End If
                
    'svuota il file batch per riempirlo di nuovo al prossimo comando
                 'Open "H:\RiservatiAccess\CreazionePgmx.bat" For Output As #1
                 '     strBatch = ""
                 'Print #1, strBatch
                 'Close #1 ' Close file.
    
    
    
        rstMateriali.MoveFirst
        Do While Not rstMateriali.EOF
            strDestinazione = Me!CartellaOutput & "\PGMX"
            strDestinazione = strDestinazione & "\" & rstMateriali!Articolo & "_" & rstMateriali!Sp
            'controlla se c'è già la cartella di output di secondo livello, se no la crea
                
                'Set fdObj = CreateObject("Scripting.FileSystemObject")
                If fdObj.FolderExists(strDestinazione) Then 'se c'è già non fa niente
                Else
                    fdObj.CreateFolder (strDestinazione)
                End If
          'comincio a creare gli xcs
            rstPezzi.MoveFirst
                Do While Not rstPezzi.EOF
                    If rstPezzi!Articolo = rstMateriali!Articolo And rstPezzi!Sp = rstMateriali!Sp Then
                            strLung = CStr(rstPezzi!Lung)
                            strLung = Replace(strLung, ",", ".")
                            strLarg = CStr(rstPezzi!Larg)
                            strLarg = Replace(strLarg, ",", ".")
                            strSp = CStr(rstPezzi!Sp)
                            strSp = Replace(strSp, ",", ".")
                            strPezzo = rstPezzi!pezzo
                            strFileUscita = strDestinazione & "\" & strPezzo & ".xcs"
                            FileCopy strOrigine, strFileUscita
                
                        strXCS = "SetMachiningParameters (""EF"", 1, 10, 0, false);"
                        strXCS = strXCS & vbCrLf & "CreateFinishedWorkpieceBox (""" & strPezzo & """," & strLung & ", " & strLarg & "," & strSp & " );"
                        strXCS = strXCS & vbCrLf & "SetWorkPieceLabel(120, 90, 90);"
                         Open strFileUscita For Output As #1
                         Print #1, strXCS
                         Close #1 ' Close file.
                     End If
                     rstPezzi.MoveNext
                Loop
                
                'modifica input e output del file batch per convertire in pgmx
                'fdObj.CopyFile "H:\RiservatiAccess\CreazionePgmx.bat", "C:\_Progetti\PGMX\U570VL_19"
                Open "H:\RiservatiAccess\CreazionePgmx.bat" For Output As #1
                Debug.Print strDestinazione
                    strBatch = "Call ""C:\Program Files\SCM Group\Maestro\XConverter.exe"" ^"
                    strBatch = strBatch & vbCrLf & "-s -m 0 ^"
                    strBatch = strBatch & vbCrLf & "-t ""C:\Users\Public\Documents\SCM Group\Maestro\Tlgx\Buzzi.tlgx"" ^"
                    strBatch = strBatch & vbCrLf & "-i """ & strDestinazione & """ ^"
                    strBatch = strBatch & vbCrLf & "-o """ & strDestinazione & """ ^"
                 Print #1, strBatch
                 Close #1 ' Close file.
                 Call Shell("H:\RiservatiAccess\CreazionePgmx.bat")
                              
                 rstMateriali.MoveNext
                  
        Loop
    
                MsgBox "Fatto"
    
    End Sub
     
  • Re: Modificare contenuto di più file di testo

    Puoi provare con una shell sincrona
    Declare Function OpenProcess Lib "kernel32" _
        (ByVal dwDesiredAccess As Long, _
        ByVal bInheritHandle As Long, _
        ByVal dwProcessID As Long) As Long
    
    Declare Function WaitForSingleObject Lib "kernel32" _
        (ByVal hHandle As Long, _
        ByVal dwmilliseconds As Long) As Long
    
    Const SYNCHRONIZE = &H100000
    Const INFINITE = &HFFFFFFFF
    '
    
    Public Function SyncShell(ProgramString As String, WinStyle As VbAppWinStyle) As Boolean
    Dim ProcessID As Long
    Dim ProcessHandle As Long
    ' In VB4, an error occurs if Shell
    ' fails to start the program
        On Error GoTo SyncShell_Error
    ' Shell the program, get its handle,
    ' and wait for it to terminate
        ProcessID = Shell(ProgramString, WinStyle)
        ProcessHandle = OpenProcess(SYNCHRONIZE, True, ProcessID)
        WaitForSingleObject ProcessHandle, INFINITE
        SyncShell = True
        Exit Function
    SyncShell_Error:
        On Error GoTo 0
        SyncShell = False
        Exit Function
    End Function
  • Re: Modificare contenuto di più file di testo

    Perfetto.
    Grazie anche se purtroppo non sono in grado di capire come funziona esattamente la funzione (hai visto il mio codice, sono molto molto basico .
    Ho però inserito prima e dopo l'esecuzione della funzione il docm.hourglass true/false.
    Piccola chicca per evitare che l'operatore continui a premere il pulsante che avvia la procedura
Devi accedere o registrarti per scrivere nel forum
8 risposte