Czasami piszemy jakiś kod i chcemy zatrzymać wykonywanie aplikacji na określony czas. Np. nasza aplikacja uruchamia jakiś zewnętrzny program i nie chcemy aby następne instrukcje wykonały się od razu, tylko po pewnym czasie (np. jak uruchomiona przez nas zewnętrzna aplikacja się wykona i zwróci wynik w postaci utworzonego pliku).
Uwaga: zakładanie na sztywno, że wstrzymanie wykonywania aplikacji na 5 sekund wystarczy, aby zewnętrzna aplikacja zdążyła „wykonać swoją robotę” jest zgubne. W przypadku różnych niekorzystnych zjawisk (wolny komputer, chwilowe przeciążenie CPU) może spowodować, że owy zewnętrzny program który uruchomiliśmy, nie wyrobi się w 5 sekund. Tutaj dobrze by było opakować nasze opóźnienie w jakąś pętlę typu Do while, która opóźnia wykonanie naszego programu o 1 sekundę ale dodatkowo sprawdza, czy owy plik już powstał i jeśli nie, to nadal czeka.
Najprostszy sposób (ale działa tylko w VBA dla Excela) to wywołanie metody Application.Wait. Oto prosty przykład:
Sub Pauza5s()
Debug.Print "Uruchomienie aplikacji o godzinie " & Now()
Application.Wait Now + TimeValue("00:00:05")
Debug.Print "Powrót do świata żywych po 5 sekundach " & Now()
End Sub
To rozwiązanie ma dwie wady. Po pierwsze: nie działa np. dla VBA dla Worda. Druga wada jest taka, że „rozdzielczość” to zaledwie 1 sekunda. Jeśli chcesz użyć mniejszego opóźnienia (np. 0,1 sekundy) to musimy skorzystać z innego rozwiązania np. wywołać odpowiednią funkcję WinAPI.
#If VBA7 Then
Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Sub Pauza100ms()
Debug.Print "Uruchomienie aplikacji o godzinie " & Now()
Sleep 100
Debug.Print "Powrót do świata żywych po 0.1 s " & Now()
End Sub
Tutaj rozdzielczość jest większa, bo teoretycznie wynosi aż 1 ms (1 sekunda = 1000 ms), ale funkcja ta nie nadaje się jeśli chcesz precyzyjnie wstrzymać wykonanie programu na baaardzo krótkie okresy czasu (sam narzut wynikający z wywołania funkcji API jest większy niż 1 ms). U mnie 1000 krotne wywołanie funkcji Sleep 1 trwało aż 16 sekund!
Uwaga: Oba te sposoby całkowicie wstrzymują wykonywanie programu. Jeśli użytkownik klika w przycisk, który wywołuje funkcję w której jest instrukcja Sleep (albo Application.Wait) to na czas wstrzymania wykonywania programu aplikacja nie reaguje na zdarzenia (nawet na tak prozaiczne rzeczy, jak np. przesunięcie okna UserForm).