Odpowiedzi:
Użyj metody Wait :
Application.Wait Now + #0:00:01#
lub (dla programu Excel 2010 i nowszych):
Application.Wait Now + #12:00:01 AM#
Application.Wait(Now + #0:00:01#)
Pozdrawiam!
Application.Wait (Now + TimeValue("0:00:01"))
Application.wait(now + 1e-5)
przez sekundę, Application.wait(now + 0.5e-5)
przez pół sekundy itd.
Dodaj to do swojego modułu
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
Lub w przypadku systemów 64-bitowych użyj:
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
Nazwij to w swoim makrze w ten sposób:
Sub Macro1()
'
' Macro1 Macro
'
Do
Calculate
Sleep (1000) ' delay 1 second
Loop
End Sub
Sleep()
pozwala określić czas oczekiwania poniżej 1 sekundy. Application.Wait
jest czasami zbyt ziarnisty.
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
zamiast używać:
Application.Wait(Now + #0:00:01#)
wolę:
Application.Wait(Now + TimeValue("00:00:01"))
ponieważ później jest o wiele łatwiejsze do odczytania.
to działa bez zarzutu dla mnie. wstaw dowolny kod przed lub po pętli „do aż”. W twoim przypadku umieść 5 wierszy (pętla time1 = & time2 = & "do till") na końcu wewnątrz pętli do
sub whatever()
Dim time1, time2
time1 = Now
time2 = Now + TimeValue("0:00:01")
Do Until time1 >= time2
DoEvents
time1 = Now()
Loop
End sub
Timer
ponieważ Timer
podejście kończy się niepowodzeniem tuż przed północą.
Deklaracja uśpienia w kernel32.dll nie będzie działać w 64-bitowym programie Excel. To byłoby trochę bardziej ogólne:
#If VBA7 Then
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#Else
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
#End If
Po prostu wyczyszczona wersja kodu Clemo - działa w programie Access, który nie ma funkcji Application.Wait.
Public Sub Pause(sngSecs As Single)
Dim sngEnd As Single
sngEnd = Timer + sngSecs
While Timer < sngEnd
DoEvents
Wend
End Sub
Public Sub TestPause()
Pause 1
MsgBox "done"
End Sub
Timer
podaje liczbę sekund od północy, to podejście nie powiedzie się, jeśli zostanie wykonane tuż przed północą (czyli np. sngEnd
> = 86 400). O północy Timer
resetuje się do 0 i pozostaje mniej niż na sngEnd
zawsze.
Większość z przedstawionych rozwiązań korzysta z Application.Wait, który nie uwzględnia czasu (milisekund), który już upłynął od rozpoczęcia bieżącego drugiego liczenia, więc mają one wewnętrzną niedokładność do 1 sekundy .
Podejście Timer jest najlepszym rozwiązaniem , ale musisz wziąć pod uwagę reset o północy, więc tutaj jest bardzo precyzyjna metoda uśpienia za pomocą Timera:
'You can use integer (1 for 1 second) or single (1.5 for 1 and a half second)
Public Sub Sleep(vSeconds As Variant)
Dim t0 As Single, t1 As Single
t0 = Timer
Do
t1 = Timer
If t1 < t0 Then t1 = t1 + 86400 'Timer overflows at midnight
DoEvents 'optional, to avoid excel freeze while sleeping
Loop Until t1 - t0 >= vSeconds
End Sub
UŻYJ TEGO DO PRZETESTOWANIA KAŻDEJ FUNKCJI UŚPIENIA: (otwórz okno debugowania Bezpośrednie okno: CTRL + G)
Sub testSleep()
t0 = Timer
Debug.Print "Time before sleep:"; t0 'Timer format is in seconds since midnight
Sleep (1.5)
Debug.Print "Time after sleep:"; Timer
Debug.Print "Slept for:"; Timer - t0; "seconds"
End Sub
Application.Wait Second(Now) + 1
Function Delay(ByVal T As Integer)
'Function can be used to introduce a delay of up to 99 seconds
'Call Function ex: Delay 2 {introduces a 2 second delay before execution of code resumes}
strT = Mid((100 + T), 2, 2)
strSecsDelay = "00:00:" & strT
Application.Wait (Now + TimeValue(strSecsDelay))
End Function
Oto alternatywa dla snu:
Sub TDelay(delay As Long)
Dim n As Long
For n = 1 To delay
DoEvents
Next n
End Sub
W poniższym kodzie wykonuję efekt "poświaty" migający na przycisku obracania, aby skierować użytkowników do niego, jeśli mają "problemy", użycie "uśpienia 1000" w pętli nie spowodowało widocznego mrugania, ale pętla działa świetnie.
Sub SpinFocus()
Dim i As Long
For i = 1 To 3 '3 blinks
Worksheets(2).Shapes("SpinGlow").ZOrder (msoBringToFront)
TDelay (10000) 'this makes the glow stay lit longer than not, looks nice.
Worksheets(2).Shapes("SpinGlow").ZOrder (msoSendBackward)
TDelay (100)
Next i
End Sub
Wykonałem to, aby rozwiązać problem:
Sub goTIMER(NumOfSeconds As Long) 'in (seconds) as: call gotimer (1) 'seconds
Application.Wait now + NumOfSeconds / 86400#
'Application.Wait (Now + TimeValue("0:00:05")) 'other
Application.EnableEvents = True 'EVENTS
End Sub
Zwykle używam funkcji Timer, aby wstrzymać aplikację. Wstaw ten kod do swojego
T0 = Timer
Do
Delay = Timer - T0
Loop Until Delay >= 1 'Change this value to pause time for a certain amount of seconds
Timer
podaje liczbę sekund od północy, to podejście nie powiedzie się, jeśli zostanie wykonane tuż przed północą (tj. Takie, które T0
jest mniejsze niż liczba sekund opóźnienia od północy). O północy Timer
resetuje się do 0 przed osiągnięciem limitu opóźnienia. Delay
nigdy nie osiąga limitu opóźnienia, więc pętla działa w nieskończoność.
Loop Until Delay >= 1
, w przeciwnym razie ryzykujesz przekroczenie 1 i nigdy nie wychodzisz z pętli.
Funkcje czekania i uśpienia blokują program Excel i nie można zrobić nic innego, dopóki opóźnienie się nie skończy. Z drugiej strony opóźnienia pętli nie dają dokładnego czasu oczekiwania.
Więc zrobiłem to obejście, łącząc trochę obu koncepcji. Powtarza się do momentu, w którym chcesz.
Private Sub Waste10Sec()
target = (Now + TimeValue("0:00:10"))
Do
DoEvents 'keeps excel running other stuff
Loop Until Now >= target
End Sub
Wystarczy zadzwonić do Waste10Sec, jeśli potrzebujesz opóźnienia
Możesz użyć Application.wait now + timevalue ("00:00:01") lub Application.wait now + timeserial (0,0,1)
DoEvents
jak pokazano