每隔10秒钟运行Application.OnTime之后,Excel最终将出现严重故障,并迫使我双击一个单元格以强制其刷新其他看似随机的行为。在仍然允许EXCEL GUI保持响应性或可靠性的同时,是否有其他选择可以经常运行任务?
要对此进行测试,我实际上运行了一个简单的VBA函数来修改多台计算机上的几个单元,问题最终持续了几分钟或几小时,或者每隔5秒钟运行一次。
一些伪代码:
Foo(){
wait 10 seconds (non blocking)
Foo()
}
答案 0 :(得分:2)
您可以在模块级别创建一个Timer。一个简单的计时器,但要注意所有必要的变量设置。否则,Excel可能会崩溃。您也可以创建一个非常稳定的Timer,但这是实现此想法的整个项目。无论如何,我可以在项目中使用这样的Timer而不会出现问题。很好的事实是,一旦启动 Timer即使在单元格编辑模式下也可以工作 ... 用下面的代码创建一个标准模块(我一直将其命名为“ Timer_module”):
Option Explicit
Declare PtrSafe Function SetTimer Lib "user32" (ByVal hWnd As LongPtr, _
ByVal nIDEvent As LongPtr, ByVal uElapse As Long, ByVal lpTimerFunc As LongPtr) As LongPtr
Declare PtrSafe Function KillTimer Lib "user32" (ByVal hWnd As LongPtr, ByVal nIDEvent As LongPtr) As Long
Private TimerID As LongPtr
Private xTimer As Long, howMany As Long
Sub StartTimer(TimerSeconds As Long, howManyTimes As Long)
howMany = howManyTimes
TimerID = SetTimer(0&, 0&, TimerSeconds * 1000, AddressOf T_Pr)
End Sub
Sub StopTimer()
On Error Resume Next
KillTimer 0, TimerID
xTimer = 0
End Sub
Sub T_Pr(ByVal hWnd As Long, ByVal uMsg As Long, _
ByVal nIDEvent As Long, ByVal dwTimer As Long)
xTimer = xTimer + 1: Debug.Print xTimer, Now
DoEvents
If xTimer = howMany Then StopTimer: Debug.Print "Timer stopped: " & Now
End Sub
在另一个模块中,可以像下面的代码中那样简单地调用Timer:
Sub testTimeer()
StartTimer 2, 4
End Sub
第一个参数表示在计时器功能执行某项操作之前必须经过的秒数。该代码可以轻松地适应毫秒级的工作。第二个参数表示计时器停止后计时器功能运行的次数。这只是一个示例,可以轻松地对其进行调整以满足您的需求。因此,您可以将其设置为仅执行一次,可以在需要时(例如,从循环中)调用`StopTimer()'过程,等等。
P.S。这样的计时器可以很容易地链接到表格。您必须注意TimerID
的定义。它应该是表单句柄。例如,通过这种方式:
TimerID = GetActiveWindow
这段代码必须是表单initialize事件的一部分,并且当然TimerID
必须是一个Public
声明的变量 ...
而且,您必须注意,当Timer运行所有其余正在运行的代码时,它必须非常稳定,并具有错误处理程序能够在发生错误时停止Timer。