Подключите Активируйте и деактивируйте события ко всем проводникам в Outlook
У меня есть некоторые методы активации / деактивации
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 изменяется, и поэтому вызывается событие деактивации.
Я хотел бы привязать события активации / деактивации ко ВСЕМ исследователям, которые может иметь Outlook, чтобы при активном переключении приложений в / из Outlook вызывались ТОЛЬКО методы активации / деактивации. Другими словами, вызывайте метод, когда я переключаюсь в Outlook из Excel, затем не вызываем событие деактивации при открытии электронных писем, планировании собраний и т. Д., Пока я не переключусь обратно в Excel.
Application.Explorers
Похоже, что возвращаются только открытые исследователи (и поэтому, когда я открываю элементы / и т. д., новые элементы создаются). Может быть возможно заставить это работать, но я не понял это.
По сути, мне нужен метод "outlook.activate" и "outlook.deactivate", который не зависит от того, какой элемент / окно Outlook я просматриваю.
1 ответ
Как я понимаю, в VBA нет способа записать событие для всех исследователей.
Чтобы обойти это, вы можете обработать событие Explorers_NewExplorer, чтобы отслеживать новых исследователей.
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 активированному.
Если у вас есть фиксированное количество исследователей (что на практике у вас всегда есть), вы можете обойти это ограничение (я бы посчитал его скорее дефектом конструкции), объявив переменную для каждого возможного исследователя и используя уродливый переключатель, например что-то вроде:
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 может быть уже переключен.