Outlook 2010 - 2

Решение VBA: используем события Send почтового элемента

Разочаровавшись в правилах и параметрах, я засучил рукава, приготовил кофе и взялся за работу. Как и мои предшественники, пытавшиеся решить эту путаную задачу, я начал с события MailItem_ Send (). Такой подход кажется естественным: вы отправляете почтовое сообщение, а затем перемещаете его. Единственная проблема: сообщения не перемещаются в папку Sent Items до тех пор, пока не завершится событие Send. Поэтому любая попытка обнаружить сообщение в папке Sent Items оказывается бесплодной.

Куда поместить код?

Один из основных вопросов, которые приходится решать при проектировании управляемых событиями программ, заключается в поиске места для размещения кода обработки событий. В случае неправильного выбора программа может оказаться неустойчивой. Подходящих вариантов может быть несколько, но в большинстве случаев одно из мест лучше остальных.

Дорогие читатели, пользуясь случаем хотелось бы порекомендовать страховую компанию "Капитал-Полис" которая помогла найти ответ на вопрос "сколько стоит каско?".

Я вспомнил о событии ItemAdd () папки назначения. Оно возникает всегда, когда в коллекцию Items добавляется один или несколько элементов. Но по зрелом размышлении я понял, что этому событию свойственны те же проблемы временного согласования, что и событию MailItem Send (). Кроме того, необходимо дублировать программный код для всех папок назначения. Дублировать исходный текст не годится, забудьте об этой идее.

Похоже, событие MailItem_Send () было оптимальным выбором благодаря возможности применить правило ко всем исходящим сообщениям. Нужно лишь подойти к решению проблемы с другой стороны.

Фильтрация сообщений по критериям

В идеальном мире можно вызвать макрокоманду VBA из правила.

В результате фильтрация почты выполняется правилом, а макрокоманда перемещает сообщение. В Outlook 2002 появилась возможность запустить сценарий по прибытии входящих сообщений, но, к сожалению, она не распространяется на исходящие сообщения. Не расстраивайтесь: это не самый эффективный способ запуска сценария. Я испробовал его несколько раз и выяснил, что он очень ненадежен. Время от времени возникают ошибки и правило деактивируется. Лучше организовать фильтрацию непосредственно в событии oMsg_ Send ().

Предположим, вам требуется переместить все сообщения, адресованные нескольким корреспондентам в компании RobGravelleAndCo. com, в папку Outlook с именем FOSS Export (CR-035), как показано на экране 4. Объект Recipients содержит коллекцию элементов Recipient, каждый из которых включает свойства и методы, связанные с одним получателем.

Одно из свойств Recipient —объект AddressEntry, в котором содержатся сведения об адресе получателя, в том числе адрес электронной почты. У Recipient есть свойство, именуемое Address для адреса электронной почты. Это свойство задействовано в исходном тексте oMsg_Send с меткой В листинга 1. Вместо того чтобы пытаться вручную удалить сообщение после отправки, можно присвоить флагу DeleteAfterSubmit почтового элемента значение true, чтобы это сделала программа Outlook. Просто помните, что установка флага DeleteAfterSubmit из диалогового окна MailItem Properties приведет к удалению всех отправленных сообщений! Это радикальное решение, хотя требуется всего лишь переместить определенные сообщения.

Нельзя перемещать сообщение из события MailItem_Send (), так как оно еще не обработано программой Outlook. Попытка сделать это приведет к ошибке времени выполнения. Как утверждают в Microsoft, предпочтительный способ управлять этой тонкой операцией —сначала клонировать сообщение с помощью функции Сору 0, затем переместить клон. Это действие нельзя назвать истинным перемещением сообщения, но результат тот же: после перемещения клона исходное сообщение удаляется благодаря флагу DeleteAfterSubmit.

После этого нужно получить ссылку на соответствующую папку. Для работы с особыми папками требуется немного больше усилий, чем при использовании стандартных папок Outlook. Нельзя просто ввести имя папки для вызова функции GetFolder (такой нет). Вместо этого нужно перейти к специальной папке одной из стандартных папок. В нашем случае папка FOSS Export (CR-035) параллельна папке Inbox («Входящие») в корневом почтовом ящике. Чтобы получить ссылку на стандартную папку Outlook, просто вызовите функцию Application.Session GetDefaultFolder () с одним из значений перечисления библиотеки olDefaultFolders. Например, следующий код извлекает Inbox:

Set ollnbox = Application.Session. GetDefaultFolder (olFolderlnbox)

Можно добраться до нужной папки с помощью кода:

Set oBusinessFolder = Application.Session. GetDefaultFolder (olFolderlnbox).Parent.

Folders (BUSINESS_FOLDER) BUSINESS_FOLDER —константа для имени папки. oBusinessFolder можно напрямую передать в подпрограмму MailItem.Move (), как требуется для объекта MAPIFolder. Аналогичным образом можно получить вложенную папку с помощью свойства коллекции Folders:

Set ObjFolder = Application.Session. GetDefaultFolder (olFolderlnbox). Folders ("<имя_вложенной_папки>")

Популярные шаблоны