Scusate il titolo troppo generico, ma non sono riuscito a riassumere la questione in poche parole.
Sto aggiungendo ad un programma una parte di codice che, attraverso un dialog, mostra vari conti alla rovescia consecutivi (in minuti/secondi/decimi), al termine di ognuno dei quali esegue un'operazione.
Il Dialog ha come elementi:
- Un timer (TimerScan)
- Una label che mostra il conto alla rovescia (LabelTime)
- Un tasto per mettere la pausa (non c'è nel codice di esempio)
- Un tasto di uscita (non c'è nel codice di esempio)
Il Problema:
Una volta avviato il timer, il programma dovrebbe dovrebbe eseguire i conti alla rovescia (due nel codice di esempio) e mostrare i tre msgbox, uno ogni volta che entra in una nuova fase.
La fase iniziale è 0, ma essendo le variabili del tempo inizializzate a 0, TimeValue sarà subito = 0 e si entrerà immediatamente nella fase 1, che darà inizio al primo conto alla rovescia per la fase due, e così via.
Quel che accade invece è un continuo apparire dei MsgBox della fase 1.
In pratica il programma entra continualmente nell'if della Sub TimerScan_Timer, esegue il MsgBox, ma NON incrementa la fase.
E questo anche se elimino il Select-Case e metto un solo MsgBox dentro l'if.
Una cosa che ho notato è che, nei primi ingressi dentro l'if, il timer mostra 0:00:-1, che non dovrebbe essere possibile.
In pratica, se tolgo il MsgBox (o qualsiasi operazione complessa al suo posto), il timer pare funzionare correttamente.
Altro strano problema è che, dopo l'unload del Dialog, continua a far apparire i MsgBox (che nell'esempio simulano le operazioni relative alle varie fasi).
PS: cerchiamo di non discutere sul fatto che un altro metodo di implementazione del counter sarebbe stato migliore o peggiore, ma sul perchè questo non funziona!!
Scrivo qui un codice riassuntivo.
codice:Option Explicit Const NUM_PHASES As Integer = 3 '// numero di fasi implementate: '// 1 -> attesa1; 2-> attesa2; 3 -> uscita Dim timeValue As Integer '// Per determinare quando il conteggio arriva a zero Dim phase As Integer '// Tiene memoria della fase in atto Dim decs As Integer Dim secs As Integer Dim mins As Integer Dim waits(NUM_PHASES) As Integer '// Ritardo tra una fase e l'altra, ossia valore di inizio '// per il conto alla rovescia. Qui per semplicità si possono '// impostare solo i secondi, da 0 a 59 '// Inizilalizzazioni Private Sub Form_Activate waits(0) = 0 waits(1) = 3 waits(2) = 4 waits(3) = 0 phase = 0 decs = secs = mins = 0 End Sub '// Valuta e decrementa il tempo, gestisce le fasi, avvia le operazioni relative alle fasi. Private Sub TimerScan_Timer() '// Aggiorno la label di visualizzazione del tempo LabelTime.Caption = FormatTime() '// Calcolo per la valutazione del tempo (se = 0 il conto alla rovescia è terminato) timeValue = decs + secs + mins If timeValue = 0 Then '// Se il conto alla rovescia è terminato '// Modifico la fase phase = phase + 1 '// Assegno il nuovo conto alla rovescia '// (Semplificato: imposto solo i sencondi) secs = waits(phase) '// Eseguo le operazioni (Qui semplificate con un MsgBox) Select Case phase Case 1 Msgbox "Fase 1" Case 2 Msgbox "Fase 2" Case Else '// Chiude il Dialog Msgbox "Fase 3" Unload Me End Select End If '// Decremento il tempo NextTime End Sub '// Decrementa decs e modifica di conseguenza i valori di secs e mins Private Sub NextTime() decs = decs - 1 If decs < 0 Then decs = 9 secs = secs - 1 If secs < 0 Then secs = 59 mins = mins - 1 End If End If End Sub '// Formatta la stringa tempo Private Function FormatTime() As String FormatTime = mins & ":" & Format(secs, "00") & ":" & decs End Function

Rispondi quotando