停止OnTime事件 [英] Stopping the OnTime event
问题描述
我碰到过很多帖子,它们解释了要取消待处理的OnTime事件,您必须提供计划运行的确切时间".
I have come across posts which explain "To cancel a pending OnTime event, you must provide the exact time that it is scheduled to run".
我应该提供事件第一次运行的时间,还是应该提供事件下次触发的时间?
Should I supply the time at which the event was run the very first time or should I supply the time at which the event will be triggered next?
我已经尝试了两个版本的StopTimer.都给我
I have tried both version of StopTimer. Both give me
对象_Application的方法OnTime失败
Method OnTime of object _Application failed
Option Explicit
Private Sub Workbook_Open()
count = 1
Call test
End Sub
Public runwhen As Double
Public Const runwhat As String = "TheSub"
Public firstrunTime As Double
Public count As Integer
Sub test()
If count = 1 Then
runwhen = Now + TimeSerial(0, 0, 5)
firstrunTime = runwhen
Else
runwhen = Now + TimeSerial(0, 0, 5)
End If
Application.OnTime runwhen, "TheSub"
End Sub
Sub TheSub()
MsgBox "Hi!!!!!!"
count = count + 1
Call test
If count = 5 Then
StopTimer
End If
End Sub
'First Version of StopTimer
Sub StopTimer()
Application.OnTime firstrunTime, "TheSub", , False
End Sub
'Second Version of StopTimer
Sub StopTimer()
runwhen=now+TimeSerial(0,0,5)
Application.OnTime runwhen, "TheSub", , False
End Sub
我在下面对过程TEST进行了更改,现在我使用的是STOPTIMER的第三版,但是我的代码却给了我同样的错误.
I made changes to procedure TEST below and now I am using third version of STOPTIMER but my code gives me same error.
Sub test()
If count = 1 Then
runwhen = Now + TimeSerial(0, 0, 5)
firstrunTime = runwhen
Else
runwhen = Now + TimeSerial(0, 0, 5)
End If
If count <> 5 Then
Application.OnTime runwhen, "TheSub"
Else
Call StopTimer
End If
End Sub
推荐答案
要取消OnTime事件,您需要告知计划运行的时间.
To cancel the OnTime event, you need to advise the time at which it is scheduled to run.
您的第一次尝试是告诉它取消一个不再计划的计划事件-它实际上可能是在几个小时前发生的.
Your first attempt was telling it to cancel a scheduled event that is no longer scheduled - it may have actually occurred several hours ago.
您的第二次尝试告诉它取消预定的事件,该事件在您决定要取消事件后5秒钟内发生.您可能很幸运,并且在决定将其设置为5秒钟后就决定尽快取消它,但您可能不会. (这取决于时钟的准确度以及计算机执行代码的速度.)
Your second attempt is telling it to cancel a scheduled event that is due to occur 5 seconds after you decided that you wanted to cancel the event. You might be lucky and have managed to decide to cancel it so soon after you set it that 5 seconds is the right time, but you probably won't be. (It depends on how accurate the clock is, and how fast your computer is executing the code.)
您需要做的就是告诉它在设置事件的同时取消该事件,因此您的代码需要说:
What you need to do is tell it to cancel the event with the same time you set it for, so your code needs to say:
'Third Version of StopTimer
Sub StopTimer()
Application.OnTime runwhen, "TheSub", , False
End Sub
该版本将使用与在测试"子例程中设置时间相同的取消时间(runwhen
).
That version will use the same time (runwhen
) in the cancellation as was used when you set the time in the Test subroutine.
更新新代码:
您可以使用代码的原始版本(与StopTimer的版本3一起使用),但是新版本将失败,因为您已将其更改为设置为runwhen
的位置.
The original version of your code would have worked (with version 3 of StopTimer), but your new version fails because you have changed it to set runwhen
when you shouldn't.
让我们逐步了解新版本代码中的情况.假设您在6:00:00 AM打开工作簿,并且您的CPU非常慢,因此我们可以为各种事件分配不同的时间.
Let's step through what is happening in the new version of the code. Assume that you open your workbook at 6:00:00 AM, and that your CPU is very slow so that we can assign various times to various events.
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事件.然后,您去取消该事件,但是不能取消该事件.
The failure occurs because you update the value of runwhen
(at 06:00:30.004 in my example), but then don't set the OnTime event. You then go to cancel the event but it isn't there to cancel.
设置OnTime事件时,应仅设置runwhen
,然后您将可以使用该变量来取消事件.
You should set runwhen
only when you are setting the OnTime event, and then you will be able to use that variable to cancel the event.
我建议您将整个代码更改为:
I recommend you change your entire code to be:
'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子例程,因为您只需将计时器启动希望运行的次数即可.
If set out that way, you don't need a StopTimer subroutine, because you only start the timer the number of times you want it to run.
但是,您可能正在尝试设计一个系统,用户可以通过单击某个按钮来决定何时停止计时器.如果是这样,您只需要在按钮的代码中包含以下语句即可停止计时器:
However, you are probably trying to design a system where the user will decide when to stop the timer, perhaps by some button click. If so, you would simply need to include in the button's code the following statement to stop the timer:
Application.OnTime runwhen, "TheSub", , False
这篇关于停止OnTime事件的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!