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