Excel VBA轮询/防止代码在指定时间内运行多次

Excel VBA轮询/防止代码在指定时间内运行多次,vba,excel,Vba,Excel,我有另一个在后台运行的代码,当满足某些条件时,它将调用子警报。虽然有多个场景调用此代码,但现在发生的是警报开始运行的频率高于我希望的3秒(由AlertTIMER指示)。下面是我解决这个问题的尝试 Sub Alert() If Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton2

我有另一个在后台运行的代码,当满足某些条件时,它将调用子警报。虽然有多个场景调用此代码,但现在发生的是警报开始运行的频率高于我希望的3秒(由AlertTIMER指示)。下面是我解决这个问题的尝试

Sub Alert()
If Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub

ElseIf Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub

ElseIf Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub

ElseIf Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub

ElseIf Sheets("Sheet1").CommandButton21.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub

ElseIf Sheets("Sheet1").CommandButton22.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub

ElseIf Sheets("Sheet1").CommandButton25.Enabled = False Then
Beep
Application.Speech.Speak ("Part is done")
Beep
Call AlertTIMER
Exit Sub
Else
Exit Sub
End If

End Sub

Sub AlertTIMER()
Dim ACountDown As Date
ACountDown = Now + TimeValue("00:00:03")
Application.OnTime ACountDown, "Alert"
End Sub
很明显,这不起作用,哈哈。最初我有一个if语句,用or代替ands。。。但这也不起作用。有什么帮助吗

编辑:

我相信在AlertTIMER sub中发生了什么,它会计算一个倒计时值。在本例中,我们假设它首先在12:00:00 AM(A倒计时将=12:00:03 AM)触发,然后将其作为该值(12:00:03 AM)分包到Application.OnTime。当触发另一个事件时,比如说在12:00:01 AM,它将计算一个倒数为12:00:04 AM,然后将其作为该值(12:00:04 AM)提交给Application.OnTime。最后我在12:00:03和12:00:04触发了“警报”。解决这一问题的一种方法是,如果代码将计数作为一个变量保留,直到从Application.OnTime触发“警报”??。因此,在上一个示例中,它首先计算12:00:03 AM进行倒计时,然后在第二个触发器进入时重置为12:00:04 AM。在凌晨12:00:04,它通过Application.OnTime触发“警报”-只运行一次

编辑2:

另一种解决方法是,如果有办法做到这一点,可以检查是否有Application.OnTime正在运行/处于活动状态,如果是,则取消它。代码如下所示:

Sub AlertTIMER()
Dim ACountDown As Date

If Application.OnTime(, "Alert") Is Nothing Then
Else
 Application.OnTime ACountDown, "Alert", , False
End If

ACountDown = Now + TimeValue("00:00:03")
Application.OnTime ACountDown, "Alert"
End Sub
Sub Alert()

    If Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton21.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton22.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep
    Else
        Exit Sub
    End If

    Call AlertTIMER

End Sub
但是
如果Application.OnTime(,“Alert”)为空,则
返回一个错误。。。因为它不是一个对象,所以你不能检查它是否为空。有没有想过我该如何让它发挥作用?

试着这样做:

Sub AlertTIMER()
Dim ACountDown As Date

If Application.OnTime(, "Alert") Is Nothing Then
Else
 Application.OnTime ACountDown, "Alert", , False
End If

ACountDown = Now + TimeValue("00:00:03")
Application.OnTime ACountDown, "Alert"
End Sub
Sub Alert()

    If Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton22.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton21.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton22.Enabled = False And Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton21.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton22.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep

    ElseIf Sheets("Sheet1").CommandButton25.Enabled = False Then
        Beep
        Application.Speech.Speak ("Part is done")
        Beep
    Else
        Exit Sub
    End If

    Call AlertTIMER

End Sub

这不完全是我想要的,但我想它完成了工作。。。这允许“嘟嘟,部分完成,嘟嘟”同步,而不是竞争。如果AlertTimer在之前已被触发(等待CurrTick到达EndTick)的情况下被触发,则EndTick将被重置,因此现在它只被触发一次。

“它不工作”不会告诉我们任何信息。告诉我们实际发生了什么,应该发生什么。举个例子也很有帮助。我知道我没有举个例子。。。至于代码,但我试图解释它:“现在发生的是警报开始运行的频率比我希望的3秒要高”换句话说,当警报在另一个代码中多次触发时,而不是听到“嘟嘟*,部分完成,嘟嘟*”等待3秒“嘟嘟*,部分完成,嘟嘟*”。。。我听到“嘟嘟*,部分完成,嘟嘟*”等待(随机秒数小于3)“嘟嘟*,部分完成,嘟嘟*”。谢谢,我相信我试过了,但它不起作用,但我会再试一次,让你知道。我现在手头没有代码。这不起作用,如果两个事件触发,那么“嘟嘟,部分完成,嘟嘟”竞争。