Excel VBA中Application.OnTime在嵌套If内无法取消如何解决
问题根因
1. 错误捕获逻辑冲突
你在copy宏开头设置了On Error GoTo ErrHandler,当If分支内的取消语句执行报错时,会直接跳转至错误处理块,你不仅无法感知报错,还会被ErrHandler内的逻辑重新注册新的定时任务,最终表现为取消语句完全不生效。
2. 取消的定时任务不存在
Application.OnTime的规则是:只有传入与注册时完全一致的时间参数,才能匹配到对应任务完成取消。且定时任务触发执行后,会自动从Excel的定时队列中移除。
你在If分支内执行取消操作时,当前触发copy宏运行的定时任务已经执行完毕,你传入的fireTime是已经过期的旧时间,Excel找不到对应任务就会抛错。此时下一次定时还没在ErrHandler中完成注册,也无任务可取消。
解决方法
使用全局停止标记控制定时启停,逻辑更简单也避免了OnTime的匹配问题:
- 新增全局停止标记变量
Public fireTime As Date Public stopCopy As Boolean ' 新增全局变量标记是否停止定时
- 修改
Userform_Initialize初始化标记
Sub Userform_Initialize() On Error Resume Next stopCopy = False ' 窗体初始化时开启定时逻辑 fireTime = Now + TimeValue("00:00:02") Application.OnTime EarliestTime:=fireTime, Procedure:="copy", Schedule:=True On Error GoTo 0 End Sub
- 修改If分支内的停止逻辑,无需调用OnTime取消
If Left(col(3), 4) = "4600" Then oData.SetText Text:=Empty 'Clear oData.PutInClipboard 'take in the clipboard to empty it UF_RegistreraVM.TB_LevNr.Text = col(0) Levnr = col(0) ' ... 其余赋值逻辑 ' 直接设置停止标记即可,无需取消OnTime stopCopy = True Exit Sub End If
- 修改错误处理块的定时注册逻辑,增加停止标记判断
ErrHandler: On Error Resume Next ' 仅当停止标记为否时才注册下一次定时 If Not stopCopy Then fireTime = Now + TimeValue("00:00:02") Application.OnTime EarliestTime:=fireTime, Procedure:="copy", Schedule:=True End If On Error GoTo 0 End Sub
- 优化
UserForm_QueryClose关闭逻辑,避免冲突
Private Sub UserForm_QueryClose(Cancel As Integer, CloseMode As Integer) stopCopy = True ' 先设停止标记,避免定时重复注册 On Error Resume Next ' 增加错误捕获,避免定时已执行完成时报错 Application.OnTime EarliestTime:=fireTime, Procedure:="copy", Schedule:=False On Error GoTo 0 End Sub
内容的提问来源于stack exchange,提问作者Andreas
相关产品推荐
相关产品推荐

