Outlook VBA: дождаться окончания работы макроса до запуска следующего макроса - PullRequest
0 голосов
/ 07 ноября 2019

У меня есть макрос в Outlook, который запускается каждый раз, когда я получаю электронное письмо с определенным именем субъекта. Проблема, с которой я сталкиваюсь в настоящее время, заключается в том, что если я получаю несколько сообщений электронной почты одновременно, которые вызывают макрос, Outlook либо зависнет, либо вылетит, либо макрос запустится только для последней полученной электронной почты и проигнорируетпредыдущие.

Учитывая это, я хотел бы спросить вас, есть ли в Outlook конфигурация (i), которая устанавливает задержку между сообщениями электронной почты, поступающими в папку «Входящие» (создавая очередь сообщений длявведите «Входящие», предоставив время для выполнения макроса до конца) или (ii) код VBA, который я мог бы использовать, чтобы макрос запускался только после завершения текущего макроса.

Спасибо за вашепомощь!

Ответы [ 2 ]

0 голосов
/ 07 ноября 2019

Ниже перечислены возможные альтернативы:

  • Обработка события NewMailEx класса Applications. Событие NewMailEx происходит, когда новое сообщение поступает в папку «Входящие» и до обработки правила клиента. Вы можете использовать идентификатор записи, возвращенный в массиве EntryIDCollection, для вызова метода NameSpace.GetItemFromID и обработки элемента. Однако в зависимости от настроек на клиентском компьютере после поступления нового сообщения в папку «Входящие» такие процессы, как фильтрация нежелательной почты и правила клиента, которые перемещают новое сообщение из папки «Входящие» в другую папку, могут происходить асинхронно.

  • Используйте таймер для периодического запуска пользовательского кода VBA. VBA ничего для этого не предоставляет, но вы можете использовать функции Windows API, перечисленные ниже:

Declare Function SetTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long, ByVal uElapse As Long, ByVal lpTimerfunc As Long) As Long
Declare Function KillTimer Lib "user32" (ByVal hwnd As Long, ByVal nIDEvent As Long) As Long

Public TimerID As Long 'Need a timer ID to eventually turn off the timer. If the timer ID <> 0 then the timer is running

Public Sub ActivateTimer(ByVal nMinutes As Long)
  nMinutes = nMinutes * 1000 * 60 'The SetTimer call accepts milliseconds, so convert to minutes
  If TimerID <> 0 Then Call DeactivateTimer 'Check to see if timer is running before call to SetTimer
  TimerID = SetTimer(0, 0, nMinutes, AddressOf TriggerTimer)
  If TimerID = 0 Then
    MsgBox "The timer failed to activate."
  End If
End Sub

Public Sub DeactivateTimer()
Dim lSuccess As Long
  lSuccess = KillTimer(0, TimerID)
  If lSuccess = 0 Then
    MsgBox "The timer failed to deactivate."
  Else
    TimerID = 0
  End If
End Sub

Public Sub TriggerTimer(ByVal hwnd As Long, ByVal uMsg As Long, ByVal idevent As Long, ByVal Systime As Long)
  MsgBox "The TriggerTimer function has been automatically called!"
End Sub
0 голосов
/ 07 ноября 2019

Все макросы выполняются в главном потоке Outlook, поэтому они всегда выполняются последовательно.

Но выполнение сценария, запускаемого правилом, не должно занять слишком много времени, иначе вы пропустите уведомления и пользовательский интерфейс перестанет отвечать на запросы. В VBA вы мало что можете сделать - вы не можете создавать вторичные потоки, и даже если бы вы могли, объекты OOM не могли быть доступны во вторичных потоках - вам нужно было бы использовать Extended MAPI (только C ++ или Delphi)или выкуп (любой язык).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...