Я пытаюсь отменить таймер в процедуре Workbook_Close в модуле ThisWorkbook. Может кто-нибудь объяснить следующее поведение ?:Application.OnTime не исполнено
Закрытие Рабочему вручную функции Application.OnTime, как ожидается, и отменяет таймер. Если я пытаюсь убить этот же таймер более чем один раз, или несуществующий таймер, я получаю сообщение об ошибке
ERROR: 1004: Method 'OnTime' of object '_Application' failed
Для меня это поддерживает доказательства того, что функция правильно работает.
Закрытие рабочей книги с помощью ThisWorkbook.Close Таймер не убит, о чем свидетельствуют факты, что:
- Учебное пособие повторно открывается, когда таймер истекает
- VBA не бросает любая ошибка, если один и тот же таймер убит более одного раза
- VBA не выдает ошибку при попытке убить несуществующий таймер
Далее Context
Application.Run пожары, как ожидается, в обоих случаях. Для меня это указывает на то, что объект приложения все еще загружен и VBA Runtime все еще функционирует должным образом.
Код проверки
В стандартном модуле под названием minUnit
Private Sub testCallBack(name As String, nextTime As String)
MsgBox "callback " & name & " " & nextTime
End Sub
Public Function sProcedure(callBackProcedure As String, mName As String, nextTime As Date) As String
' Constructs a properly formatted string to feed to OnTime for a call back with two parameters
sProcedure = "'" & callBackProcedure & " " & """" & mName & """," & """" & fmtTime(nextTime) & """'"
End Function
Private Sub testTimerSet()
gnextTime = Now() + TimeSerial(1, 0, 0)
Application.OnTime gnextTime, sProcedure("Globals.testCallBack", _
"testTimer", gnextTime)
End Sub
Public Sub testTimerKill()
On Error Resume Next
Application.OnTime gnextTime, sProcedure("Globals.testCallBack", _
"testTimer", gnextTime), _
, False
End Sub
В ThisWorkbook
Private Sub Workbook_BeforeClose(Cancel As Boolean)
Globals.testTimerKill
Globals.testTimerKill
Globals.testTimerKill
On Error Resume Next
Application.OnTime 0, "Nothing", , False
Application.Run sProcedure("minUnit.testCallBack", "Application.Run", Now())
Application.OnTime Now(), sProcedure("minUnit.testCallBack", "Application.OnTime Now()", Now()), , True
End Sub
Sub closeWorkbook()
ThisWorkbook.Close
End Sub
трассировки для ручного закрытия (ошибки, возникающие, как и ожидалось) ...
20:27:07:206 minUnit.testTimerSet: START 20:27:07:209 Application.OnTime 'minUnit.testCallBack "testTimer","21:27:07"' :0.003532 20:27:07:212 minUnit.testTimerSet: END :0.006447 20:27:13:618 minUnit.testTimerKill: START 20:27:13:621 minUnit.testTimerKill: END :0.003337 20:27:21:240 minUnit.testTimerSet: START 20:27:21:244 Application.OnTime 'minUnit.testCallBack "testTimer","21:27:21"' :0.004301 20:27:21:246 minUnit.testTimerSet: END :0.006274 20:27:33:946 ThisWorkbook.Workbook_BeforeClose: START 20:27:33:949 minUnit.testTimerKill: START 20:27:33:951 minUnit.testTimerKill: END :0.001921 20:27:33:953 minUnit.testTimerKill: START 20:27:33:957 minUnit.testTimerKill: END 20:27:33:957**ERROR: 1004: Method 'OnTime' of object '_Application' failed :0.002433 20:27:33:963 minUnit.testTimerKill: START 20:27:33:967 minUnit.testTimerKill: END 20:27:33:967**ERROR: 1004: Method 'OnTime' of object '_Application' failed :0.002230 20:27:33:972 Application.OnTime 0, "Nothing", , False 20:27:33:972**ERROR: 1004: Method 'OnTime' of object '_Application' failed :0.024134 20:27:33:977 Application.Run 'minUnit.testCallBack "Application.Run","20:27:33"' :0.031184 20:27:33:983 minUnit.testCallBack: START 20:27:35:995 minUnit.testCallBack: END :2.012402 20:27:35:997 Application.OnTime Now() 'minUnit.testCallBack "Application.OnTime Now()","20:27:35"':2.051651 20:27:35:999 ThisWorkbook.Workbook_BeforeClose: END :2.053604
трассировки для закрытия с .close запустив closeWorkbook (должен забросили первую ошибку в 20: 30: 11: 979) ...
20:29:48:201 minUnit.testTimerSet: START 20:29:48:204 Application.OnTime 'minUnit.testCallBack "testTimer","21:29:48"' :0.003342 20:29:48:206 minUnit.testTimerSet: END :0.005207 20:29:51:942 minUnit.testTimerKill: START 20:29:51:945 minUnit.testTimerKill: END :0.002946 20:29:55:444 minUnit.testTimerSet: START 20:29:55:448 Application.OnTime 'minUnit.testCallBack "testTimer","21:29:55"' :0.003535 20:29:55:450 minUnit.testTimerSet: END :0.005446 20:30:11:966 ThisWorkbook.closeWorkbook: START 20:30:11:971 ThisWorkbook.Workbook_BeforeClose: START 20:30:11:973 minUnit.testTimerKill: START 20:30:11:975 minUnit.testTimerKill: END :0.001994 20:30:11:979 minUnit.testTimerKill: START 20:30:11:981 minUnit.testTimerKill: END :0.001847 20:30:11:983 minUnit.testTimerKill: START 20:30:11:986 minUnit.testTimerKill: END :0.002271 20:30:11:988 Application.OnTime 0, "Nothing", , False :0.016905 20:30:11:991 Application.Run 'minUnit.testCallBack "Application.Run","20:30:11"' :0.019140 20:30:11:996 minUnit.testCallBack: START 20:30:13:976 minUnit.testCallBack: END :1.979131 20:30:13:977 Application.OnTime Now() 'minUnit.testCallBack "Application.OnTime Now()","20:30:13"':2.005963 20:30:13:985 ThisWorkbook.Workbook_BeforeClose: END :2.013265
testTimerKill действительно был ошибочной пастой ... спасибо, что указал, что сейчас исправлено. Я перепроверю оставшуюся часть вашего анализа и отчитаюсь. –
Ваш ответ не распространяется на режим сбоя, который происходит, когда рабочая книга закрыта с помощью кода 'ThisWorkbook.Close' –
@CoolBlue Я обновил свой ответ, включая решение для вашего запроса. Пожалуйста, попробуйте и отчитайтесь. Как-то, убивая таймер перед запуском таймера снова, решает эту проблему. Вид фанки, поскольку таймер уже прошел, однако это был единственный способ остановить таймер из макроса CloseWB. – TAKL