2014-11-14 105 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

相关问题