[RIsolto] Rendere SINCRONO l' esecuzione di un exe

di il
4 risposte

[RIsolto] Rendere SINCRONO l' esecuzione di un exe

Salve a tutti ho un problema con i tempi di risposta del computer, mi spiego meglio ho creato questo codice
'inzio a calcolare il tempo ed apro la clessidra
Inizio = Now()
DoCmd.Hourglass True

'seleziono i pdf temporanei
    Dim StrFile As String
    StrFile = Dir(CurrentProject.Path & "\pdfVecchio\*.pdf")

'inizio il ciclo
    Do While Len(StrFile) > 0

'creo il txt temp
    Dim File As String
    File = CurrentProject.Path & "\pdfVecchio\" & StrFile
    creoTemp = CurrentProject.Path & "\pdftotext.exe " & Chr(34) & File & Chr(34) & " " & CurrentProject.Path & "\Temp.txt"
    Shell creoTemp, vbHide

'attendo 0.6 sec che si crei il file temp
    Dim PauseTime As Variant, Start As Variant, Elapsed As Variant
    PauseTime = 0.6 'secondi pausa
    Start = Timer
    Elapsed = 0
    Do While Timer < Start + PauseTime
    Elapsed = Elapsed + 1
    If Timer = 0 Then
    PauseTime = PauseTime - Elapsed
    Start = 0
    Elapsed = 0
    End If
    DoEvents
    Loop
    
'apro il file temp
Open CurrentProject.Path & "\Temp.txt" For Input As #1

'attendo 0.2 sec che si apra il file temp
    Dim PauseTime3 As Variant, Start3 As Variant, Elapsed3 As Variant
    PauseTime3 = 0.2 'secondi pausa
    Start3 = Timer
    Elapsed3 = 0
    Do While Timer < Start3 + PauseTime3
    Elapsed3 = Elapsed3 + 1
    If Timer = 0 Then
    PauseTime3 = PauseTime3 - Elapsed3
    Start3 = 0
    Elapsed3 = 0
    End If
    DoEvents
    Loop

'Leggo il file temp e seleziono l'anno il titolo ed il codice fiscale
Line Input #1, riga1
anno = Mid(riga1, 21, 4)
Line Input #1, riga2
Line Input #1, riga3
titolo = Mid(riga3, 4, 3)
Line Input #1, riga4
Line Input #1, riga5
Line Input #1, riga6
Line Input #1, riga7
Line Input #1, riga8
Line Input #1, riga9
Line Input #1, riga10
Line Input #1, riga11
Line Input #1, riga12
Line Input #1, riga13
Line Input #1, riga14
Line Input #1, riga15
Line Input #1, riga16
Line Input #1, riga17
Line Input #1, riga18
Line Input #1, riga19
Line Input #1, riga20
Line Input #1, riga21
Line Input #1, riga22
Line Input #1, riga23
Line Input #1, riga24
Line Input #1, riga25
Line Input #1, riga26
cf = riga26
Close #1

'rinomino file pdf in base al titolo codice fiscale ed anno
Dim nomevecchio
Dim nomenuovo As String
nomevecchio = File
nomenuovo = sFolder & "\CUD" & titolo & cf & anno & "0000000000000000.pdf"

'elimino il vecchio pdf e creo il nuovo pdf rinominato
Name nomevecchio As nomenuovo

'elimino txt temporaneo
Kill CurrentProject.Path & "\Temp.txt"
StrFile = Dir

'vado al prossimo pdf se questo non è l'ultimo
Loop

'altrimenti chiudo il ciclo
    End If
End With

'chiudo la clessidra
DoCmd.Hourglass False

'calcolo il tempo impiegato
Fine = Now()
totale = DateDiff("s", Inizio, Fine)

'mando il messaggio di fine app con il tempo impiegato
MsgBox ("PDF Rinominati Tempo impiegato " & totale & " sec."), vbInformation
in patrica prende tutti i pdf presenti in una determinata cartella
tramite il programma pdftotext.exe crea un txt con i dati presenti nel pdf
legge i dati nelle linee 1, 3 e 26 e rinomina i pdf con i dati che ha rilevato
il mio problema sta nel fatto che al momento di aprire il txt
Open CurrentProject.Path & "\Temp.txt" For Input As #1
dopo circa 10 pdf si blocca perchè non lo trova, e lo stesso errore me lo dà quando inizia a leggere il txt
Line Input #1, riga1
quindi ho risolto mettendo un timer di circa 0.6 sec all' apertura del txt e di 0.2 sec alla lettura del txt
oltre al fatto che non mi piace dal punto di vista concettuale il problema è che se il computer fa altre operazioni si sballa lo stesso
quindi ho pensato di aggiungere un codice per fare andare avanti solo se il file txt esiste quindi ho scritto

Line1:
ctrltemp = len(dir(currentProject.path & "\Temp.txt"))
If ctrltemp >0 Then
Open CurrentProject.Path & "\Temp.txt" For Input As #1
else
GoTo Line1
end if
ma così mi elebora solo un pdf e poi finisce
ho notato che il problema stà nel crtltemp
infatti se scrivo
ctrltemp = len(dir(currentProject.path & "\Temp.txt"))
deubug.Print ctrltemp
mi fà sempre solo un pdf e finisce

come posso risolvere il problema?

4 Risposte

  • Re: [RIsolto] Rendere SINCRONO l' esecuzione di un exe

    Prova a sostituire i timer con questo codice
    Dim wshell As Object
    Set wshell = VBA.CreateObject("WScript.Shell")
    Dim waitOnReturn As Boolean: waitOnReturn = True 'True = lo script interrompe l'esecuzione finché l'utente non esce dall'applicazione avviata, False = lo script continua a funzionare dopo aver avviato l'applicazione.
    Dim windowStyle As Integer: windowStyle = 0
    
    'Per proseguire il codice solo alla fine della chiamata shell
    wshell.Run Mettilatuaistruzioneeedaeseguire, windowStyle, waitOnReturn
    vedi come va ....
  • Re: [RIsolto] Rendere SINCRONO l' esecuzione di un exe

    Il problema non è l'apertura del FILE... ma l'esecuzione della SHELL al File [pdftotext.exe] che è ASINCRONA.

    Ora la questione dei TIMER non c'entra nulla, anzi proprio è da rimuovere, ma è molto equivoco il suggerimento di MARMAURO, che non va a sostituire il TIMER quanto la chiamata SHELL.
    L'uso di WSH con il parametro Wait rende SINCRONA l'esecuzione della conversione da PDF a TXT effettuata dal SW, di conseguenza poi tutto il resto del codice è già SINCRONO e vedrai che funziona.

    Una cosa simile come logica..., ma il codice che hai scritto è pessimo come pulizia, dichiari variabili interne a LOOP, cosa che non si può vedere, poi hai disseminato dichiarazioni ovunque, non coerenti... non hai messo la GESTIONE ERRORI, se qualche cosa non funziona ti rimane in HourGlass... insomma... prova a fare pulizia e scrivere in modo decente...!
    'inzio a calcolare il tempo ed apro la clessidra
    Inizio = Now()
    DoCmd.Hourglass True
    
    'seleziono i pdf temporanei
    Dim File As String
    Dim StrFile As String
    StrFile = Dir(CurrentProject.Path & "\pdfVecchio\*.pdf")
    
    Dim wshell As Object
    Set wshell = VBA.CreateObject("WScript.Shell")
    
    'inizio il ciclo
    Do While Len(StrFile) > 0
    
    	'creo il txt temp
    
        File = CurrentProject.Path & "\pdfVecchio\" & StrFile
        creoTemp = CurrentProject.Path & "\pdftotext.exe " & Chr(34) & File & Chr(34) & " " & CurrentProject.Path & "\Temp.txt"
    	wshell.Run creoTemp, vbHide, True
       
    	'apro il file temp
    	Open CurrentProject.Path & "\Temp.txt" For Input As #1
    	'Leggo il file temp e seleziono l'anno il titolo ed il codice fiscale
    		Line Input #1, riga1
    		anno = Mid(riga1, 21, 4)
    		Line Input #1, riga2
    		Line Input #1, riga3
    		titolo = Mid(riga3, 4, 3)
    		Line Input #1, riga4
    		Line Input #1, riga5
    		Line Input #1, riga6
    		Line Input #1, riga7
    		Line Input #1, riga8
    		Line Input #1, riga9
    		Line Input #1, riga10
    		Line Input #1, riga11
    		Line Input #1, riga12
    		Line Input #1, riga13
    		Line Input #1, riga14
    		Line Input #1, riga15
    		Line Input #1, riga16
    		Line Input #1, riga17
    		Line Input #1, riga18
    		Line Input #1, riga19
    		Line Input #1, riga20
    		Line Input #1, riga21
    		Line Input #1, riga22
    		Line Input #1, riga23
    		Line Input #1, riga24
    		Line Input #1, riga25
    		Line Input #1, riga26
    		cf = riga26
    	Close #1
    
    	'rinomino file pdf in base al titolo codice fiscale ed anno
    	Dim nomevecchio
    	Dim nomenuovo As String
    	nomevecchio = File
    	nomenuovo = sFolder & "\CUD" & titolo & cf & anno & "0000000000000000.pdf"
    
    	'elimino il vecchio pdf e creo il nuovo pdf rinominato
    	Name nomevecchio As nomenuovo
    
    	'elimino txt temporaneo
    	Kill CurrentProject.Path & "\Temp.txt"
    	StrFile = Dir
    
    	'vado al prossimo pdf se questo non è l'ultimo
    Loop
    
    'chiudo la clessidra
    DoCmd.Hourglass False
    Set wshell =Nothing
    'calcolo il tempo impiegato
    Fine = Now()
    totale = DateDiff("s", Inizio, Fine)
    
    'mando il messaggio di fine app con il tempo impiegato
    MsgBox ("PDF Rinominati Tempo impiegato " & totale & " sec."), vbInformation
  • Re: [RIsolto] Rendere SINCRONO l' esecuzione di un exe

    Buongiorno, grazie per i suggerimenti.
    Ora, utilizzando i suggerimenti di Alex, il programma funziona ho un pò di quesiti, per non fare gli stessi errori in futuro.
    1° il problema quindi era dovuto al fatto che lo shell era ASINCRONO, e questo lo avevo subintuito, quindi per rendorlo SINCRONO bisogna creare un oggetto Wscript.Shell e poi lanciarlo giusto?
    nel codice
    wshell.Run creoTemp, vbHide, True
    il true a che serve?
    2° ho visto in giro qualcuno che per lanciare un programma tramite shell utilizza un .bat a me sembra più lento, che differenza c'è?
    3° nel mio codice c'era end with ed end if alla fine, l end if ovviamente non serviva perchè si collegava al filedialog che non ho postato ma Alex hai tolto anche l' end with, è un refuso e c'è qualcosa che sbaglio dato che senza il codice non funziona?
    4° le dichiarazioni dentro un ciclo non si mettono per un discorso di pulizia del codice(che condivido) o hanno altre criticità?
    5° quando mi dici che ci sono delle Dichiarazioni non coerenti ti riferisci solo alle variant che c'erano nel codice di pausa o ce ne sono altre errate?
    6° Hai ragione per le dichiarazioni solo che quando scrivo un codice e ne aggiungo dei pezzi li metto quando mi servono e poi dimentico di sistemarle
    7° devo iniziare ad imparare la gestione degli errori grazie ad Alex ho iniziato ad apprezzare il debug
    grazie sempre
    PS Ho cambiato il titolo per spiegare meglio l' argomento
  • Re: [RIsolto] Rendere SINCRONO l' esecuzione di un exe

    eternityck ha scritto:


    Buongiorno, grazie per i suggerimenti.
    Ora, utilizzando i suggerimenti di Alex, il programma funziona ho un pò di quesiti, per non fare gli stessi errori in futuro.
    1° il problema quindi era dovuto al fatto che lo shell era ASINCRONO, e questo lo avevo subintuito, quindi per rendorlo SINCRONO bisogna creare un oggetto Wscript.Shell e poi lanciarlo giusto?
    nel codice
    wshell.Run creoTemp, vbHide, True
    il true a che serve?

    eternityck ha scritto:


    2° ho visto in giro qualcuno che per lanciare un programma tramite shell utilizza un .bat a me sembra più lento, che differenza c'è?
    Che è una idea bizzarra, nemmeno riesci a controllare il risultato... ma in giro si vedono tante cose strane...

    eternityck ha scritto:


    3° nel mio codice c'era end with ed end if alla fine, l end if ovviamente non serviva perchè si collegava al filedialog che non ho postato ma Alex hai tolto anche l' end with, è un refuso e c'è qualcosa che sbaglio dato che senza il codice non funziona?
    Nel codice che hai postato, peraltro molto MAL INDENTATO, non trovo il WITH iniziale, motivo per cui ho eliminato il resto, ma come ti dicevo scrivi male il codice ed ho PULITO perchè a me piace codice perfetto, ora se manca ripristina in base a quanto serve ma usa l'INDENTAZIONE corretta.

    eternityck ha scritto:


    4° le dichiarazioni dentro un ciclo non si mettono per un discorso di pulizia del codice(che condivido) o hanno altre criticità?
    Ogni volta che dichiari una Variabile la RESETTI oltre che ad impegnare nuova area di memoria... ti pare normale...?
    Le dichiarazioni delle Variabili si fanno in testa alle Funzioni/Sub in modo da sapere da subito quali risorse ci sono a disposizione è questione di ORDINE ed anche perchè se scrivi ROUTINE lunghe, sai sempre dove trovare i riferimenti e non si dissemina nel codice.

    eternityck ha scritto:


    5° quando mi dici che ci sono delle Dichiarazioni non coerenti ti riferisci solo alle variant che c'erano nel codice di pausa o ce ne sono altre errate?
    Mi riferisco ad esempio a questo:
    
    Dim nomevecchio
    Dim nomenuovo As String
    Mi riferisco al fatto che usi 26 Variabili RIGA, in modo relativamente utile, basta un ARRAY string con un Ciclo per eseguire quel codice che porta via 3 righe invece di 28...

    eternityck ha scritto:


    6° Hai ragione per le dichiarazioni solo che quando scrivo un codice e ne aggiungo dei pezzi li metto quando mi servono e poi dimentico di sistemarle
    7° devo iniziare ad imparare la gestione degli errori grazie ad Alex ho iniziato ad apprezzare il debug
    grazie sempre
    PS Ho cambiato il titolo per spiegare meglio l' argomento
    Sicuramente scrivere codice è facile... scriverlo bene molto meno, scriverlo che funzioni e che sia ottimizzato per nulla scontato.
Devi accedere o registrarti per scrivere nel forum
4 risposte