我有一些激活/停用的方法
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
似乎只返回打开的探索者(因此,当我打开项目等时,似乎会创建新的项目)。也许有可能让它发挥作用,但我还没有弄清楚。
本质上,我想要一个"outlook.activate"one_answers"outlook.dectivate"的方法,它与我正在查看的outlook项目/窗口无关。
据我所知,VBA中没有办法为所有资源管理器捕获事件。
若要解决此问题,您可以处理Explorers_NewExplorer事件来跟踪新的Explorers。
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.ActiveNExplorer都指向正在停用的资源管理器,因此无法检测哪个资源管理器被激活。我们需要知道这一点,因为我们需要将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可能已经切换。