Vba 将激活和停用事件连接到Outlook中的所有资源管理器

Vba 将激活和停用事件连接到Outlook中的所有资源管理器,vba,event-handling,outlook-2007,Vba,Event Handling,Outlook 2007,我有一些激活/停用方法 Private Sub myOlExp_Activate() 'stuff End Sub Private Sub myOlExp_Deactivate() End Sub 它们通过连接到Explorer对象 Public WithEvents myOlExp As Outlook.Explorer Set myOlExp = Application.ActiveExplorer (called in the "Application_Startup" method)

我有一些激活/停用方法

Private Sub myOlExp_Activate()
'stuff
End Sub

Private Sub myOlExp_Deactivate()
End Sub
它们通过连接到Explorer对象

Public WithEvents myOlExp As Outlook.Explorer
Set myOlExp = Application.ActiveExplorer (called in the "Application_Startup" method)
但是,当我打开一封电子邮件、事件或其他东西时,ActiveExplorer似乎会发生变化,因此会调用deactivate事件

我希望将激活/停用事件绑定到Outlook可以拥有的所有资源管理器,以便仅在我将应用程序切换到Outlook或从Outlook切换应用程序时调用激活/停用方法。换句话说,当我从Excel切换到Outlook时调用该方法,然后在打开电子邮件、安排会议等时不调用停用事件,直到我切换回Excel

Application.Explorers
似乎只返回打开的探索者(因此,当我打开项目/etc时,似乎会创建新的项目)。也许可以让它工作,但我还没有弄明白


基本上,我需要一个“outlook.activate”和“outlook.deactivate”方法,该方法独立于我正在查看的outlook项目/窗口。

据我所知,VBA无法为所有探索者捕获事件

Dim WithEvents exps As Outlook.Explorers
Private Sub Application_Startup()
    Set exps = Application.Explorers
    Set exp = Application.ActiveExplorer
End Sub
Private Sub exps_NewExplorer(ByVal Explorer As Explorer)
    Set exp = Explorer
End Sub
要解决此问题,您可以处理探索者\新探索者事件以跟踪新探索者

Dim WithEvents exps As Outlook.Explorers
Private Sub Application_Startup()
    Set exps = Application.Explorers
    Set exp = Application.ActiveExplorer
End Sub
Private Sub exps_NewExplorer(ByVal Explorer As Explorer)
    Set exp = Explorer
End Sub
现在的主要问题是跟踪激活情况。由于您只有一个绑定到事件的对象,因此我们需要找到一种方法,将该对象分配给新激活的资源管理器。 不幸的是,下面的自然尝试无效:

Private Sub exp_Deactivate()
    Debug.Print ("Win: " & Application.ActiveWindow.Caption & ", Expl: " & Application.ActiveExplorer.Caption)
    If Application.ActiveWindow.Class = olExplorer Then
         Set exp = Application.ActiveWindow   ' Caveat: This does not work!
    End If
End Sub
由于Explorer_Deactivate事件是在开关生效之前触发的,即Application.ActiveWindow和Application.ActiveExplorer都指向要停用的资源管理器,因此无法检测哪个资源管理器被激活。我们需要知道,因为我们需要将exp分配给激活的exp

如果你有一个固定数量的探索者(实际上你一直都有),你可以通过声明变量来处理这个限制(我把它看作是一个设计缺陷) 对于每个可能的资源管理器,请使用丑陋的开关,例如:

Private Sub exp1_Aactivate()
    ... call your sub here ...
End Sub
Private Sub exp2_Activate()
    ... call your sub here ...
End Sub

Private Sub exps_NewExplorer(ByVal Explorer As Explorer)
    Select Case Application.Explorers.Count
        Case 1
            Set expl1 = Explorer
        Case 2
            Set expl2 = Explorer
        ... etc ...
不幸的是,我还没有找到一种方法,如何在从旧资源管理器触发的任何事件中检测新的活动资源管理器。
一种可能(但仍然很难看)的方法是,如果你可以启动一个计时器,几毫秒后ActiveWindow可能已经被切换了。

这就是我描述的问题吗?