Excel 试图理解application.ontime

Excel 试图理解application.ontime,excel,vba,Excel,Vba,我写了一段代码,到目前为止,它可以在“单一任务需求”中工作。 这是一个简单的警报 用户必须在a列的任何单元格中键入一个数字。该数字表示警报触发前所需的秒数 只有当用户双击a列中带有数字的单元格时,时间才会开始运行。我们将其称为“呼叫单元格”” 双击后,“调用单元格”变为红色(表示开始运行的时间),在该时间量(以秒为单位)之后,将触发一个名为“无限_Msgbox”的例程,并开始每5秒运行一次 “Infinite\u Msgbox”将“主叫单元”变为绿色,并简单地(在消息框中)显示它应该被触发的时间

我写了一段代码,到目前为止,它可以在“单一任务需求”中工作。 这是一个简单的警报

用户必须在a列的任何单元格中键入一个数字。该数字表示警报触发前所需的秒数

只有当用户双击a列中带有数字的单元格时,时间才会开始运行。我们将其称为“呼叫单元格”

双击后,“调用单元格”变为红色(表示开始运行的时间),在该时间量(以秒为单位)之后,将触发一个名为“无限_Msgbox”的例程,并开始每5秒运行一次

Infinite\u Msgbox”将“主叫单元”变为绿色,并简单地(在消息框中)显示它应该被触发的时间。并不断重复此消息,直到用户再次双击“呼叫单元”,此时该单元变为白色,报警停止

如果用户在触发“Infinite\u Msgbox”之前双击“主叫单元”,则报警将被取消,并且“主叫单元”再次变为白色

如果A列中只有一个单元格被双击,一切正常。 如果我尝试设置第二个警报,而其中一个警报已经在运行,那么该进程会变得非常奇怪,并且“Infinite\u Msgbox”只显示第二次双击时应该显示的时间。 它会不断显示两个消息框,但不在正确的时间范围内

我使用一个数组来跟踪每次双击,但Application.OnTime似乎并不关心它

Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean)
  
    If Target.Column = 1 Then
        iAlarm = Target.Row
        If iAlarm > iHighest_Alarm Then
            iHighest_Alarm = iAlarm
        End If
    
        If (Target.Interior.Color = vbWhite) Then
            Target.Interior.Color = vbRed
            Call Alarm_Setup(Target.Value, Target.Row)
        ElseIf (Target.Interior.Color = vbRed) Then
            Target.Interior.Color = vbWhite
            Call Alarm_Cancel(Target.Row)
        Else
            Target.Interior.Color = vbWhite
            Call Alarm_Stop(Target.Row)
        End If
    End If
 
    Cancel = True

End Sub
这是一个模块:

Public iAlarm As Integer
Public iHighest_Alarm As Integer
Public dTime_to_Alarm() As Double
Public dTime_to_Stop_Alarm() As Double

Public Sub Alarm_Setup(ByVal sTime_to_Alarm As String, ByVal iRow As Integer)

    ReDim Preserve dTime_to_Alarm(1 To iHighest_Alarm)
    dTime_to_Alarm(iAlarm) = Now + TimeSerial(0, 0, Val(sTime_to_Alarm))
    Application.OnTime dTime_to_Alarm(iAlarm), "'Infinite_MsgBox """ & iRow & "'"

End Sub

Public Sub Infinite_MsgBox(ByVal iRow As Integer)

    Cells(iRow, 1).Interior.Color = vbGreen
    MsgBox "Alarm " & iAlarm & ": " & CDate(dTime_to_Alarm(iAlarm))

    ReDim Preserve dTime_to_Stop_Alarm(1 To iHighest_Alarm)
    dTime_to_Stop_Alarm(iAlarm) = Now + TimeSerial(0, 0, 5)

    Application.OnTime dTime_to_Stop_Alarm(iAlarm), "'Infinite_MsgBox """ & iRow & "'"

End Sub

Public Sub Alarm_Cancel(ByVal iRow As Integer)

    Application.OnTime EarliestTime:=dTime_to_Alarm(iAlarm), Procedure:="'Infinite_MsgBox """ & iRow & "'", Schedule:=False

End Sub

Public Sub Alarm_Stop(ByVal iRow As Integer)

    Application.OnTime EarliestTime:=dTime_to_Stop_Alarm(iAlarm), Procedure:="'Infinite_MsgBox """ & iRow & "'", Schedule:=False

End Sub
那么,我如何才能让Application.OnTime按预期工作?..

尝试以下方法:

工作表代码

Private子工作表\u双击之前(ByVal目标作为范围,Cancel作为布尔值)
变暗rw为长
如果Target.Column=1,则
如果不是数字(Target.Value),则退出Sub
rw=Target.Row
选择Case Target.Interior.Color
案例vbWhite
Target.Interior.Color=vbRed
报警设置目标值,rw
其他情况
Target.Interior.Color=vbWhite
报警取消rw
结束选择
Cancel=True“仅在列A中取消?”?
如果结束
端接头
模块代码-根据单元格行,使用脚本字典跟踪下一次执行时间

作为对象的公共报警
公共子报警设置(ByVal秒为字符串,ByVal rw为长)
暗dt
'如果尚未创建词典,请创建词典
如果Alarms为Nothing,则设置Alarms=CreateObject(“scripting.dictionary”)
dt=现在+时间序列(0,0,Val(秒))
Application.OnTime dt,“'Infinite_MsgBox'&rw&'”
报警(rw)=dt'将行和下一次添加到字典
端接头
公共子无限大_MsgBox(ByVal rw等长)
Dim dt,ws As工作表
设置ws=ThisWorkbook.Worksheets(“我的报警”)或其他内容
ws.Cells(rw,1).Interior.Color=vbGreen
调试。打印“报警”,rw,报警(rw)
dt=现在+时间序列(0,0,5)
Application.OnTime dt,“'Infinite_MsgBox'&rw&'”
报警(rw)=dt'下一次运行时更新
端接头
公共子报警\u取消(ByVal rw尽可能长)
'检查此行是否有任何计划
如果存在报警(rw),则
Application.OnTime EarliesTime:=报警(rw)_
过程:=“'Infinite_MsgBox'&rw&'”_
附表:=假
警报。删除rw“从警报中删除”
如果结束
端接头