我做了一本工作手册,在10分钟不活动后必须关闭。我使用Application.OnTime的计时器。我在每分钟不活动后使用Application.OnTime命令刷新状态栏中的消息。在最后一分钟,我在每秒不活动后使用Application.OnTime命令来加速状态栏中的消息。 这很好用,到目前为止都很好。
Public dtNextTime As Date
Public lngWaitTime As Long
Public lngRefreshTime As Long
Sub StartCountDownTimer()
Call StopCountDownTimer
dtNextTime = 0
lngWaitTime = 1 * 60 ' In my real workbook, the user can change the 10 minutes in a cell and I use this value in this sub
' Set initial RefreshTime
lngRefreshTime = 60
Call PlanNextTime
End Sub
Sub PlanNextTime()
Dim strWaitTime As String
Dim lngShowWaitTime As Long
If lngWaitTime >= 60 Then
lngShowWaitTime = lngWaitTime / 60
Else
lngShowWaitTime = lngWaitTime
End If
Select Case lngWaitTime
Case Is >= 120
strWaitTime = " minutes"
Case Is >= 60
strWaitTime = " minute"
Case Is > 1
strWaitTime = " seconds"
Case Is = 1
strWaitTime = " second"
End Select
Application.StatusBar = "If you don't use this workbook it will be closed in " & lngShowWaitTime & strWaitTime
If lngWaitTime <= 0 Then
Application.StatusBar = "Workbook is being closed"
Call CloseWorkbook
Else
If dtNextTime = 0 Then dtNextTime = Now()
If lngWaitTime > 60 Then
lngRefreshTime = 60
Else
lngRefreshTime = 1
End If
Application.OnTime EarliestTime:=dtNextTime, Procedure:="PlanNextTime", Schedule:=True
dtNextTime = dtNextTime + TimeSerial(0, 0, lngRefreshTime)
lngWaitTime = lngWaitTime - lngRefreshTime
End If
End Sub
Sub StopCountDownTimer()
On Error Resume Next
Application.OnTime EarliestTime:=dtNextTime, Procedure:="PlanNextTime", Schedule:=False
On Error GoTo 0
Application.StatusBar = False
End Sub
Sub CloseWorkbook()
' In my real workbook, at this place I call a sub to do some final things like saving the workbook
Application.StatusBar = False
ThisWorkbook.Close
End Sub
为了测试这个,我只用了最后一分钟。然后我发现我在其他手动启动的程序中遇到了奇怪的问题。我的初步结论是:您无法一起运行使用Application.OnTime命令启动的过程的手动启动过程。我想我可以找到一个解决方法,但我想确定我的结论是正确的。 Excel VBA应该是单线程的,所以我不确定我的结论是否正确。
因此,我的问题是:是否有人熟悉使用Application.OnTime命令触发的过程的问题,在手动启动过程运行的同时触发? 你知道怎么处理这个问题吗?
答案 0 :(得分:1)
我认为您的问题是,您创建的Event
在现有例程运行时不会触发。你推测的原因是正确的:Excel VBA是单线程的。
也许你的“手动启动”程序是修改大表中的记录或类似的?如果是这种情况,请在循环中插入DoEvents
以允许计划触发任何待处理事件。这将导致运行跳转到您的预定子例程(PlanNextTime()
)并在返回循环之前完成该操作。
我发布的代码没有太大的错误,但我承认我没有完全通过它来检查你的聪明但令人困惑的分钟与秒处理。我确实注意到您似乎没有在StopCountDownTimer()
内拨打CloseWorkbook()
。这可能意味着在关闭工作簿,甚至完全关闭Excel时,Excel将在关闭后重新打开工作簿以运行您的下一个计划事件。