2014-11-14 86 views
-3

我們被要求不要再由我們的客戶使用Application.OnTime。這是我們的先決條件,對不起,我們無法控制。我們可以使用.NET System.Windows.Forms.Timer來替換Excel VBA Application.onTime嗎?

但由於我們需要定期運行一些任務,我們需要找到一個替代計時器。我們已經嘗試了System.Timers.Timer,但它對Microsoft Excel有一些問題。原因是Microsoft Excel不支持多線程,但System.timers.timer使用多線程。

所以現在我們要試試System.Windows.Forms.Timer。這個計時器使用Windows消息泵,它似乎應該適用於Microsoft Excel。我們可以在C#中使用System.Windows.Forms.Timer,然後定期向VBA引發一個事件。

從Kenny Kerr的文章http://weblogs.asp.net/kennykerr/Rtd3看來,我們的想法很好。但是有人可以深入瞭解System.Windows.Forms.Timer的工作原理,並從底層理論中回答爲什麼它可以工作。

+3

這聽起來像是在要求別人爲你做你的研究。 – 2014-11-14 17:46:52

+0

其實我做了很多研究,但是我還是沒有得到答案。 – 2014-11-14 17:50:22

+0

而您希望其他人「深入挖掘並弄清楚System.Windows.Forms.Timer的工作方式」 – 2014-11-14 17:51:21

回答

1

是,在以前的答覆工作計時器,是我們目前的解決方案。 現在我們要將此解決方案移至C#。

現在我確認System.Windows.Forms.Timer可以使用excel,因爲它是以隱藏窗體的形式註冊窗口消息循環。所以線程總是和excel主線程一樣。那麼它在Excel中工作。

您可以使用GetCurrentThreadId API來確認它。

2

如果是VBA應用程序,爲什麼要使用.NET API?除非您因其他原因已經這樣做,例如它使用VSTO。

使用Application.OnTime而不使用.NET的替代方法是使用Win32 API(SetTimer/KillTimer)。

這裏有讓你開始的一些代碼的提取物(這不是一個完整的工作示例):

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

Private m_TimerID As Long 

Private Sub StartTimer() 
    m_TimerID = SetTimer(0&, 0&, 100&, AddressOf TimerProc) 
End Sub 

Private Sub EndTimer() 
    On Error Resume Next 
    KillTimer 0&, m_TimerID 
End Sub 

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

    EndTimer 

    ... do your stuff here. Call StartTimer to start the timer again if desired 
End Sub 
+0

非常感謝。我們已經嘗試過這種方式。現在我們的團隊正在討論有關system.windows.forms.time的內容。我們想知道可以替換應用程序。準時 – 2014-11-14 18:11:25

相關問題