2017-06-16 31 views
1

我在Excel中使用Windows API計時器(用於VBA的初學者),同時調查爲什麼Excel會一直崩潰,想到這個問題。在TimerProc完成每隔X秒後運行其他子集(Excel VBA中的API SetTimer)

在有幾個子宏的宏中,第一個子程序啓動運行TimerProc代碼的定時器,比如說每5秒鐘一次。啓動計時器後,第一個子結束,下一個開始。其他功能在第二個子程序中調用,程序在達到定時器5秒之前結束。所以在技術上,整個宏在TimerProc被調用的時候完成。

此時,是否可以在TimerProc代碼結束之後運行/調用任何其他子函數或函數的任何其他部分?很顯然你可以在TimerProc代碼中進行調用,但結束後如何?例如,如果在TimerProc中執行KillTimer,但是我沒有重新啓動TimerProc中的定時器,有沒有辦法在別的地方重新啓動定時器?

注:我使用主叫視窗定時器的方法在http://www.cpearson.com/excel/OnTime.aspx

嘗試實施例詳述:

Public Declare Function SetTimer Lib "user32" (_ 
    ByVal HWnd As Long, _ 
    ByVal nIDEvent As Long, _ 
    ByVal uElapse As Long, _ 
    ByVal lpTimerFunc As Long) As Long 

Public Declare Function KillTimer Lib "user32" (_ 
    ByVal HWnd As Long, _ 
    ByVal nIDEvent As Long) As Long 

Public TimerID As Long 
Public TimerSeconds As Single 

Sub StartTimer() 
    TimerSeconds = 10000 ' how often to "pop" the timer, in milliseconds 
    TimerID = SetTimer(0&, 0&, TimerSeconds, AddressOf TimerProc) 
End Sub 

Sub EndTimer() 
    'On Error Resume Next 
    KillTimer 0&, TimerID 
End Sub 

Sub TimerProc(ByVal HWnd As Long, ByVal uMsg As Long, _ 
     ByVal nIDEvent As Long, ByVal dwTimer As Long) 

    timerFinished = True 
    Call EndTimer 
    'Instead of calling StartTimer here inside TimerProc, I want to exit TimerProc and re-run the below sub, which will now call StartTimer 

End Sub 

Sub exampleSub() 

    Call StartTimer 

    If timerFinished = True Then 
     Msgbox "It worked!" 
     call StartTimer 
    End If   
End Sub 

計時器目前設置爲10秒,並且示例Sub將在10秒命中之前肯定已經完成運行,並且TimerProc是a可以運行並將timerFinished bool更改爲True。有沒有辦法,一旦TimerProc完成,重新運行exampleSub(現在timerFinished爲True)重新啓動計時器沒有在TimerProc本身調用StartTime?我想確保TimerProc完全結束。

回答

0

要啓動exampleSub TimerProc`完成後,您可以使用:

Application.OnTime Now, "exampleSub" 

上述語句指示VBA開始exampleSub儘快,當前的處理後(所有程序目前在調用堆棧)完成。

順便說一句,您可以使用Application.OnTime循環來解決您的原始問題,而無需使用SetTimer API。後者只有在需要以毫秒計時時纔有意義,而OnTime的單位爲1秒。

+0

A.S.H謝謝你的迴應。我將在哪裏將'Application.OnTime Now,「exampleSub」'放在程序中?如果我把它放在TimerProc的任何地方,那麼在TimerProc被調用後,程序如何知道何時回到它?另外,我確實需要比秒更多的分辨率,特別是十分之一秒。 – jdyagoda

+0

@jdyagoda我想你的評論的地方*「而不是在這裏TimerProc裏面調用StartTimer,我想退出TimerProc並重新運行下面的子,現在將調用StartTimer」*。該語句將完全實現:'TimerSub'一旦'TimerProc'返回(它不會再出現在調用堆棧中)就會被激活。 –

+0

如果您在'exampleSub'中放置斷點,並顯示調用堆棧。你可以驗證沒有任何東西超過它...除了VBA運行時間... –