【发布时间】:2010-12-05 09:31:30
【问题描述】:
我有一个包含以下宏的 Excel 工作表。我想每秒循环一次,但如果我能找到执行此操作的函数,我会冒险。不可以吗?
Sub Macro1()
'
' Macro1 Macro
'
Do
Calculate
'Here I want to wait for one second
Loop
End Sub
【问题讨论】:
我有一个包含以下宏的 Excel 工作表。我想每秒循环一次,但如果我能找到执行此操作的函数,我会冒险。不可以吗?
Sub Macro1()
'
' Macro1 Macro
'
Do
Calculate
'Here I want to wait for one second
Loop
End Sub
【问题讨论】:
使用Wait method:
Application.Wait Now + #0:00:01#
或(对于 Excel 2010 及更高版本):
Application.Wait Now + #12:00:01 AM#
【讨论】:
DoEvents 在这里演示 dailydoseofexcel.com/archives/2005/06/14/stopwatch
Application.Wait(Now + #0:00:01#) 干杯!
Application.Wait (Now + TimeValue("0:00:01"))
Application.wait(now + 1e-5) 秒,Application.wait(now + 0.5e-5) 半秒等等。
将此添加到您的模块中
Public Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)
或者,对于 64 位系统使用:
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
像这样在你的宏中调用它:
Sub Macro1()
'
' Macro1 Macro
'
Do
Calculate
Sleep (1000) ' delay 1 second
Loop
End Sub
【讨论】:
Sleep() 允许您指定小于 1 秒的等待时间。 Application.Wait 有时过于细化。
Public Declare PtrSafe Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As LongPtr)
而不是使用:
Application.Wait(Now + #0:00:01#)
我更喜欢:
Application.Wait(Now + TimeValue("00:00:01"))
因为以后读起来容易很多。
【讨论】:
这对我来说完美无缺。在“do until”循环之前或之后插入任何代码。在您的情况下,将 5 行(time1= & time2= & "do until" 循环)放在您的 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 的类似解决方案效果更好,因为Timer 方法在午夜前失败。
kernel32.dll 中的睡眠声明在 64 位 Excel 中不起作用。这会更笼统一些:
#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
【讨论】:
只是 clemo 代码的清理版本 - 在 Access 中工作,它没有 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 给出自午夜以来的秒数,那么如果它在午夜之前执行,则此方法将失败(即,sngEnd >= 86,400)。在午夜,Timer 重置为 0,因此永远小于 sngEnd。
大多数提出的解决方案都使用 Application.Wait,它不考虑自当前秒计数开始以来已经过去的时间(毫秒),因此 它们具有高达 1 秒的内在不精确度.
Timer 方法是最好的解决方案,但是你必须考虑到午夜的重置,所以这里有一个非常精确的使用 Timer 的 Sleep 方法:
'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
使用它来测试任何睡眠功能:(打开调试立即窗口: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
【讨论】:
等待和睡眠功能会锁定 Excel,在延迟结束之前您无法执行任何其他操作。另一方面,循环延迟不会给你一个确切的等待时间。
所以,我做了这个解决方法,加入了这两个概念。它循环直到时间是你想要的时间。
Private Sub Waste10Sec()
target = (Now + TimeValue("0:00:10"))
Do
DoEvents 'keeps excel running other stuff
Loop Until Now >= target
End Sub
你只需要在你需要延迟的地方调用Waste10Sec
【讨论】:
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
【讨论】:
这是睡眠的替代方法:
Sub TDelay(delay As Long)
Dim n As Long
For n = 1 To delay
DoEvents
Next n
End Sub
在下面的代码中,我在旋转按钮上制作了一个“发光”效果闪烁,以便在用户“遇到问题”时将其引导到它,在循环中使用“睡眠 1000”导致没有可见的闪烁,但循环是工作得很好。
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
【讨论】:
我做了这个来回答这个问题:
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
【讨论】:
我通常使用 Timer 功能来暂停应用程序。将此代码插入您的代码
T0 = Timer
Do
Delay = Timer - T0
Loop Until Delay >= 1 'Change this value to pause time for a certain amount of seconds
【讨论】:
Timer 给出了从午夜开始的秒数,那么如果它在午夜之前执行,则此方法将失败(即,T0 小于从午夜开始的延迟秒数) .在午夜,Timer 在达到延迟限制之前重置为 0。 Delay 永远不会达到延迟限制,所以循环永远运行。
Loop Until Delay >= 1,否则你可能会超过 1 并且永远不会退出循环。
试试这个:
Threading.thread.sleep(1000)
【讨论】:
你可以使用 Application.wait now + timevalue("00:00:01") 要么 Application.wait now + timeserial(0,0,1)
【讨论】: