等待OnTime事件触发然后完成(OnTime任务优先级)

时间:2019-07-12 16:28:58

标签: excel vba ontime

我想澄清我对Excel的VBA Application.OnTime调度程序在调用其分配的过程时的操作的理解。特别是,如果在下一个计划的OnTime时间的3秒内,用户单击运行子例程的UserForm按钮,则我希望该子例程等待OnTime的过程开始,然后继续等待直到该过程结束,然后再继续它自己的活动(以避免冲突,两个例程可以访问相同的文件,等等)。如果用户在3s间隔之前单击一个按钮,则计划的计时器将被简单地取消,然后再重新计划。

我相信VBA不支持多线程,因此我认为OnTime调度程序必须与所有其他UserForm和Module例程在同一VBA线程单元中运行其分配的过程。从某些测试中可以看出,分配的OnTime过程在被触发时具有优先权,从而冻结了当时可能已经在运行的任何其他子例程的执行。

以下尝试似乎可行。请参阅其中的一些注释,以了解可能发生的情况。

Public NextCallTime As Date ' (Set as OnTime time for next scheduled procedure)
Public TimerRunning As Boolean  ' (True when OnTime's procedure has been scheduled, False when procedure finishes)

...

Public Sub WaitForTimerTaskComplete()
    Dim CurrentCallTime As Date

    CurrentCallTime = NextCallTime ' Make a local copy to 'freeze' the applicable time value 
'(because 'NextCallTime' could be updated by the time this Sub unfreezes to finish waiting)

'   Wait until timer task commences, if within 3s from now...

    If TimerRunning And DateDiff("s", Now(), CurrentCallTime) < 3 Then

'      Loop into the frozen state induced by the timer task...

       While DateDiff("s", Now(), CurrentCallTime) > -2: DoEvents: Wend 
'    [I use -2 as a 2-second overlap to ensure that the task has started (not guaranteed though)]

'      Then continue to wait until timer task has finished, which updates 'NextCallTime' 
'      via a subsequent OnTime call [This line is probably redundant in all cases, because 
'      this Sub seems to freeze (and so effectively wait) until the timer task has finished!]...

       While TimerRunning And CurrentCallTime = NextCallTime: DoEvents: Wend 
    End If
End Sub

我担心的是,一旦计划的任务开始,我将依靠上面的模块代码冻结作为“等待”功能的一部分。这是一种可靠的方法吗(OnTime过程是否总是中断并且优先于观察中可能出现的过程)?如果不使用API​​,是否会有更好的方法?

谢谢, 约翰。

0 个答案:

没有答案