Подключите Активируйте и деактивируйте события ко всем проводникам в 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 может быть уже переключен.

Другие вопросы по тегам