要取消OnTime事件,您需要通知计划运行的时间。
您的第一次尝试是告诉它取消不再计划的预定事件 - 实际上它可能发生在几个小时前。
您的第二次尝试是告诉它取消预定的事件,该事件在您决定要取消事件后5秒内发生。你可能是幸运的,并设法决定取消它很快,你设置5秒是正确的时间,但你可能不会。 (这取决于时钟的准确度以及计算机执行代码的速度。)
您需要做的是告诉它在您设置的同一时间取消该事件,因此您的代码需要说:
'Third Version of StopTimer
Sub StopTimer()
Application.OnTime runwhen, "TheSub", , False
End Sub
该版本将使用相同的时间(runwhen
)在取消当您设置的测试子程序时使用。
更新重新新代码:
代码的最初版本会工作(与StopTimer的版本3),不过新版本失败,因为你已经改变了它设置runwhen
你的时候不应该。
让我们逐步了解新版本代码中正在发生的事情。假设您在上午6:00:00打开工作簿,并且CPU速度非常慢,以便我们可以为各种事件分配各种时间。
06:00:00.000 - Workbook opens
06:00:00.001 - Subroutine Test is called
06:00:00.002 - Count is 1, so first If statement executes the first section
06:00:00.003 - runwhen is set to 06:00:05.003
06:00:00.004 - firstruntime is set to 06:00:05.003
06:00:00.005 - Count is 1, not 5, so second If statement executes the first section
06:00:00.006 - OnTime is set to run TheSub at 06:00:05.003
06:00:00.007 - Subroutine Test finishes and control returns to TheSub
06:00:00.008 - Count is 1, not 5, so If statement is not executed
06:00:00.009 - Subroutine TheSub finishes and execution of macro stops
06:00:05.003 - OnTime event triggers
06:00:05.004 - Subroutine TheSub is called
06:00:05.005 - MsgBox is displayed
The user is very slow to press the button this time. (Mainly because I had
written a lot of the following times, and then realised my Count was out
by 1, and I didn't want to have to rewrite everything - so I just added
a very slow response here.)
06:00:12.000 - User presses OK
06:00:12.001 - Count is set to 2
06:00:12.002 - Subroutine Test is called
06:00:12.003 - Count is 2, not 1, so first If statement falls into Else portion
06:00:12.004 - runwhen is set to 06:00:17.004
06:00:12.005 - Count is 2, not 5, so second If statement executes the first section
06:00:12.006 - OnTime is set to run TheSub at 06:00:17.004
06:00:12.007 - Subroutine Test finishes and control returns to TheSub
06:00:12.008 - Count is 2, not 5, so If statement is not executed
06:00:12.009 - Subroutine TheSub finishes and execution of macro stops
06:00:17.004 - OnTime event triggers
06:00:17.005 - Subroutine TheSub is called
06:00:17.006 - MsgBox is displayed
06:00:18.000 - User presses OK
06:00:18.001 - Count is set to 3
06:00:18.002 - Subroutine Test is called
06:00:18.003 - Count is 3, not 1, so first If statement falls into Else portion
06:00:18.004 - runwhen is set to 06:00:23.004
06:00:18.005 - Count is 3, not 5, so second If statement executes the first section
06:00:18.006 - OnTime is set to run TheSub at 06:00:23.004
06:00:18.007 - Subroutine Test finishes and control returns to TheSub
06:00:18.008 - Count is 3, not 5, so If statement is not executed
06:00:18.009 - Subroutine TheSub finishes and execution of macro stops
06:00:23.004 - OnTime event triggers
06:00:23.005 - Subroutine TheSub is called
06:00:23.006 - MsgBox is displayed
06:00:24.000 - User presses OK
06:00:24.001 - Count is set to 4
06:00:24.002 - Subroutine Test is called
06:00:24.003 - Count is 4, not 1, so first If statement falls into Else portion
06:00:24.004 - runwhen is set to 06:00:29.004
06:00:24.005 - Count is 4, not 5, so second If statement executes the first section
06:00:24.006 - OnTime is set to run TheSub at 06:00:29.004
06:00:24.007 - Subroutine Test finishes and control returns to TheSub
06:00:24.008 - Count is 4, not 5, so If statement is not executed
06:00:24.009 - Subroutine TheSub finishes and execution of macro stops
06:00:29.004 - OnTime event triggers
06:00:29.005 - Subroutine TheSub is called
06:00:29.006 - MsgBox is displayed
06:00:30.000 - User presses OK
06:00:30.001 - Count is set to 5
06:00:30.002 - Subroutine Test is called
06:00:30.003 - Count is 5, not 1, so first If statement falls into Else portion
06:00:30.004 - runwhen is set to 06:00:35.004
06:00:30.005 - Count is 5, so second If statement executes falls into the Else portion
06:00:30.006 - Subroutine StopTimer is called
06:00:30.007 - Code attempts to cancel Ontime event scheduled for 06:00:35.004 (the value of runwhen),
but fails because no such event is scheduled)
的失败是因为你更新的runwhen
值(在06:00:在我的例子30.004),但后来不设置导通时间的事件。然后你去取消这个活动,但它不能取消。
当您设置OnTime事件时,您应该设置runwhen
只有,然后您将能够使用该变量取消该事件。
我建议你改变你的整个代码为:
'In your Workbook module
Option Explicit
Private Sub Workbook_Open()
count = 1
Call StartTimer
End Sub
'In your main code module
Option Explicit
Public runwhen As Double
Public count As Integer
Sub TheSub()
MsgBox "Hi!!!!!!"
count = count + 1
Call StartTimer
End Sub
Sub StartTimer()
If count <> 5 Then
runwhen = Now + TimeSerial(0, 0, 5)
Application.OnTime runwhen, "TheSub"
End If
End Sub
如果设置了这种方式,你不需要StopTimer子程序,因为你只启动定时器,你希望它的次数跑。
但是,您可能正试图设计一个系统,用户可以决定何时停止计时器,也许可以通过点击某个按钮。如果是这样,你只需要在按钮的代码,以包括以下语句停止定时器:
Application.OnTime runwhen, "TheSub", , False
如果在StopTimer的第三个版本中没有“On Error Resume Next”语句,Test子例程将继续运行。我在我的机器上试过了。 –
@ Anastasiya-Romanova秀 - 没有错误处理程序,如果尝试取消OnTime事件失败,则会生成错误消息。错误处理程序只会导致执行继续而不会崩溃。您可能认为需要On Error的原因是,当OP将'runwhen'设置为新的不同时间时,会发生崩溃。你的最新答案删除了'runwhen'的重置,所以'On Error'也可以被删除。 – YowE3K
如果我没有弄错,OP希望Test子例程必须在count = 5时结束,但如果没有On Error Resume Next,它将继续运行。 –