如何检查或取消excel VBA中的多个挂起的application.ontime事件?

我正在使用Application.Ontime事件从单元格拉出一个时间字段,并安排一个子程序在那个时候运行。 我的Application.Ontime事件在Workbook_BeforeSave事件上运行。 因此,如果用户(更改所需时间+保存工作簿)多次,则创build多个Application.Ontime事件。 理论上我可以跟踪每个事件的唯一时间variables..但有没有办法检查/parsing/取消未决事件?

Private Sub Workbook_BeforeSave SendTime = Sheets("Email").Range("B9") Application.OnTime SendTime, "SendEmail" End Sub Private Sub Workbook_BeforeClose Application.OnTime SendTime, "SendEmail", , False End Sub 

所以如果我:
将B9更改为12:01,保存该工作簿
将B9更改为12:03,保存该工作簿
将B9更改为12:05,保存该工作簿
将B9更改为12:07,保存该工作簿
等等

我结束了多个事件发射。 我只想要一个事件(最近预定​​的)

如何取消Workbook_BeforeClose事件上的所有未决事件(或至less枚举它们)?

我不认为你可以遍历所有未决的事件或在一个shabang中全部取消。 我build议设置一个模块级别或全局布尔值指示是否触发您的事件。 所以你最终会得到这样的东西:

 Dim m_AllowSendMailEvent As Boolean Sub SendMail() If Not m_AllowSendMailEvent Then Exit Sub 'fire event here End Sub 

编辑:

将其添加到表单模块的顶部,其中包含您所在的date/时间值的范围:

 ' Most recently scheduled OnTime event. (Module level variable.) Dim PendingEventDate As Date ' Indicates whether an event has been set. (Module level variable.) Dim EventSet As Boolean Private Sub Worksheet_Change(ByVal Target As Range) Dim SendTimeRange As Range ' Change to your range. Set SendTimeRange = Me.Range("B9") ' If the range that was changed is the same as that which holds ' your date/time field, schedule an OnTime event. If Target = SendTimeRange Then ' If an event has previously been set AND that time has not yet been ' reached, cancel it. (OnTime will fail if the EarliestTime parameter has ' already elapsed.) If EventSet And Now > PendingEventDate Then ' Cancel the event. Application.OnTime PendingEventDate, "SendEmail", , False End If ' Store the new scheduled OnTime event. PendingEventDate = SendTimeRange.Value ' Set the new event. Application.OnTime PendingEventDate, "SendEmail" ' Indicate that an event has been set. EventSet = True End If End Sub 

而这一个标准模块:

 Sub SendEmail() 'add your proc here End Sub 

或者你可以创build一些单元格(如算盘),例如:

如果我使用application.ontime:

 if range("V1") < 1 then Application.OnTime dTime, "MyMacro" range("V1")=range("V1") + 1 end if 

如果我想停止计数…

  Application.OnTime dTime, "MyMacro", , False range("V1")=range("V1") - 1 

每次调用Application.Ontime时,都要保存事件设置为运行的时间(可以将其保存在工作表或模块范围的dynamic数组中)

每次事件触发时,请删除相应的保存时间

要取消所有待处理的事件,请调用Application.Ontime with schedule = false遍历剩余的保存时间

根据已经提出的一些build议,我想我可能会有一个解决scheme。

简而言之,我们创build一个全局数组,并且每次用户点击save SendTime被写入数组。 这有助于跟踪我们所有的预定时间。

当工作簿closures时,我们遍历数组并删除所有计划的时间。

我testing了这个,它似乎在Excel 2003上工作。让我知道你如何继续。

 Dim scheduleArray() As String //Set as global array to hold times Private Sub Workbook_BeforeSave SendTime = Sheets("Email").Range("B9") AddToScheduleArray SendTime Application.OnTime SendTime, "SendEmail" End Sub Private Sub Workbook_BeforeClose On Error Resume Next Dim iArr As Integer, startTime As String For iArr = 0 To UBound(scheduleArray) - 1 //Loop through array and delete any existing scheduled actions startTime = scheduleArray(iArr) Application.OnTime TimeValue(startTime), "SendEmail", , False Next iArr End Sub Sub AddToScheduleArray(startTime As String) Dim arrLength As Integer If Len(Join(scheduleArray)) < 1 Then arrLength = 0 Else arrLength = UBound(scheduleArray) End If ReDim Preserve scheduleArray(arrLength + 1) //Resize array scheduleArray(arrLength) = startTime //Add start time End Sub