停止准时事件

在搜寻了很多post之后,我仍然无法回头。 请告诉我如何停止Application.Ontime事件。 我遇到过解释To cancel a pending OnTime event, you must provide the exact time that it is scheduled to runpostTo cancel a pending OnTime event, you must provide the exact time that it is scheduled to run

现在我的问题是我应该提供事件第一次运行的时间,还是应该提供下一个事件触发的时间?

我已经在下面的代码都试过StopTimer的版本,他们都给我"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 

请填写我缺less的东西

我已经对下面的程序TEST进行了更改,现在我正在使用第三个版本的STOPTIMER,但是我的代码仍然给出了同样的错误

 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事件,您需要通知计划运行的时间。

你的第一个尝试是告诉它取消一个不再计划的预定事件 – 实际上可能发生在几个小时之前。

您的第二次尝试是告诉它取消在您决定取消事件后5秒内发生的预定事件。 你可能很幸运,并设法决定取消5秒是正确的时间,但你可能不会。 (这取决于时钟的准确度,以及计算机执行代码的速度。)

你需要做的是告诉它在你设置的同一时间取消事件,所以你的代码需要说:

 'Third Version of StopTimer Sub StopTimer() Application.OnTime runwhen, "TheSub", , False End Sub 

该版本将使用与在Test子例程中设置时间时使用的相同时间( 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事件。 您然后去取消事件,但它不是在那里取消。

只有当您设置OnTime事件时,您应该设置runwhen ,然后您将能够使用该variables来取消事件。

我build议你改变你的整个代码是:

 '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子例程,因为您只需要启动计时器就可以运行它的次数。

但是,您可能正试图devise一个系统,用户可以决定何时停止计时器,也许只需点击一下button即可。 如果是这样,你只需要在button的代码中包含以下语句来停止计时器:

 Application.OnTime runwhen, "TheSub", , False 

你的代码在我的机器上正常工作。 在这里,我使用StopTimer子例程的第二个版本,并把所有的代码放在标准的代码模块中。 我认为你的代码中的罪魁祸首是你不声明全局variables:

 Public runwhen As Double Public Const runwhat As String = "TheSub" Public firstrunTime As Double Public count As Integer 

代码模块的顶部 。 把它们放在Option Explicit下面,以使它们正常工作。

FWIW,我修复你的StopTimer子程序的第一个版本,使其正常工作:

 Sub StopTimer() On Error Resume Next Application.OnTime runwhen, "TheSub", , False End Sub 

现在这两个子例程都可以互换使用。