【发布时间】:2020-09-20 11:47:43
【问题描述】:
我在 Excel VBA 中有代码,我喜欢每秒运行几次。
在我使用这种方法之前:
Application.On Time Now + Timevalue("00:00:01")
虽然这种方法只能处理秒数(并且不能处理毫秒数)。
出于这个原因,我用毫秒计时器替换了这个计时器(参见下面的代码)。 虽然由于我将毫秒计时器与我的其他 Excel VBA 代码集成,它有时会给出此错误:“意外错误 35010”。
这个错误有几个原因提到:
VBA compile Error: unexpected error 35010
我确实在两台计算机上测试了代码,并且在两台计算机上都返回了错误。 我还在 Excel Pro Plus 2019 和 Excel Pro Plus 2016 上进行了测试。都是 64 位版本。两者都返回错误。
由于我预计这是由于文件损坏,我确实制作了一个新工作簿并将所有 VBA 代码复制到此工作簿中。我从空工作表开始,将旧工作簿中的所有公式复制到新工作簿表中。尽管这些文件仍然返回错误,但我这样做了两次。
错误总是在我启动代码后直接发生。该错误不涉及特定的代码行(黄色)。
有时会发生错误,而完全相同的文件和内容不会发生错误。
这是计时器的代码:
Option Explicit
Private Declare PtrSafe Function SetTimer Lib "user32" _
(ByVal hWnd As LongPtr, _
ByVal nIDEvent As LongPtr, _
ByVal uElapse As Long, _
ByVal lpTimerFunc As LongPtr) As LongPtr
Private Declare PtrSafe Function KillTimer Lib "user32" _
(ByVal hWnd As LongPtr, _
ByVal nIDEvent As LongPtr) As Long
Private m_TimerID As LongPtr
'Note: The duration is measured in milliseconds.
' 1,000 milliseconds = 1 second
Public Sub StartTimer(ByVal Duration As Long)
'If the timer isn't already running, start it.
If m_TimerID = 0 Then
If Duration > 0 Then
m_TimerID = SetTimer(0, 0, Duration, AddressOf TimerEvent)
If m_TimerID = 0 Then
MsgBox "Timer initialization failed!"
End If
Else
MsgBox "The duration must be greater than zero."
End If
Else
MsgBox "Timer already started."
End If
End Sub
Public Sub StopTimer()
'If the timer is already running, shut it off.
If m_TimerID <> 0 Then
KillTimer 0, m_TimerID
m_TimerID = 0
Else
MsgBox "Timer is not active."
End If
End Sub
Public Property Get TimerIsActive() As Boolean
'A non-zero timer ID indicates that it's turned on.
TimerIsActive = (m_TimerID <> 0)
End Property
这是我如何使用计时器的示例代码:
Public CountSomething As Variant
Private timerRunning As Boolean
Sub UPDATECLOCK()
''Application.Calculation = xlManual
If Not timerRunning Then
CountSomething = 0
r = 0
StartTimer 100
timerRunning = True
End If
End Sub
Sub STOPCLOCK()
StopTimer
timerRunning = False
End Sub
Sub TimerEvent()
On Error GoTo ErrHandler
'force code to run on the main thread instead of Windows api thread:
If timerRunning Then Application.OnTime Now, "updateWorksheet"
Exit Sub
ErrHandler:
Debug.Print Err.Number
End Sub
Sub updateWorksheet()
'call code to process here
'or this example code in this case:
CountSomething = CountSomething + 1
Worksheets("Sheet1").Cells(2, 9).Value = CountSomething
'write 1 in cel A1 to stop code running:
knop = ActiveSheet.Cells(1, 1)
If knop = 1 And timerRunning Then
StopTimer
timerRunning = False
End If
End Sub
有谁知道错误的原因是什么?
非常感谢!
【问题讨论】:
-
如果您使用毫秒,则更容易执行
(TimeValue("00:50:00") / 1000)之类的操作。例如Application.Wait Now + (TimeValue("00:50:00") / 1000)将暂停代码 3000 毫秒(3 秒) -
@Foxfire And Burns And Burns 谢谢,虽然 Excel 应用程序在使用 Wait 时被冻结,这对我来说不可行。
-
由于您的
Timer函数只有一秒的精度,您是在 Mac 上运行吗? -
@Ron Rosenfeld 的确如此,这就是我尝试使用此 Windows API 解决方案的原因。我正在使用 Excel Pro Plus 64 位的 Windows 10 Pro 64 位运行。
-
不知道您可以在 Mac 上使用 Windows API。我认为您可以使用
evaluate("=now()")来获得毫秒精度。在 Windows 上,我通常使用 hiRes 计时器,它使用滴答计数来获取时间间隔。互联网上的例子比比皆是。
标签: excel vba winapi timer milliseconds