停止OnTime事件 [英] Stopping the OnTime event

查看:162
本文介绍了停止OnTime事件的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我碰到过很多帖子,它们解释了要取消待处理的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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆