При интеграции 1С с почтовыми сервисами разработчики часто сталкиваются с выбором: использовать стандартный объект ИнтернетПочта или взаимодействовать с установленным в системе клиентом Microsoft Outlook через COM-соединение. Использование MAPI (Messaging Application Programming Interface) через Outlook оправдано в тех случаях, когда требуется специфический функционал, например, работа с отчетами о доставке и прочтении, которые не всегда корректно обрабатываются типовыми средствами платформы.
Однако при работе через COM возникает распространенная проблема: 1С подключается к папкам Outlook, но новые письма с сервера не загружаются до тех пор, пока пользователь вручную не откроет приложение Outlook и не инициирует сеанс связи. В этой статье мы подробно разберем, как программно заставить Outlook синхронизировать почту и какие методы MAPI наиболее эффективны для автоматизации работы с письмами.
Рассмотрим стандартную ситуацию: разработчик подключается к объекту Outlook.Application, получает доступ к пространству имен MAPI и перебирает сообщения в папке «Входящие». Проблема заключается в том, что по умолчанию COM-объект обращается к локальному кэшу (файлу .pst или .ost). Если фоновое приложение Outlook не выполнило команду «Отправить и получить», новые данные с сервера в локальную базу не попадут.
Проанализируем типичный фрагмент кода, который считывает почту, но страдает от отсутствия синхронизации:
Оутлук = Новый COMОбъект("Outlook.Application");
ПространствоИмен = Оутлук.GetNamespace("MAPI");
Для Каждого Аккаунт Из ПространствоИмен.Stores Цикл
Если Аккаунт.GetDefaultFolder(6).Store.DisplayName = "почта@example.org" Тогда
КоллекцияВходящие = Аккаунт.GetDefaultFolder(6).Items;
// Здесь мы видим только то, что уже было скачано ранее
КонецЕсли;
КонецЦикла;
В данном примере число 6 в методе GetDefaultFolder(6) соответствует стандартной папке входящих сообщений (olFolderInbox).
Самый простой и эффективный способ инициировать синхронизацию конкретной папки — использование свойства InAppFolderSyncObject. Это заставляет Outlook рассматривать папку как активную для синхронизации в текущей сессии. Разберем исправленный вариант кода:
// Получаем доступ к папке Входящие
Инбокс = Аккаунт.GetDefaultFolder(6);
// Включаем синхронизацию для этой папки
Инбокс.InAppFolderSyncObject = Истина;
// Теперь коллекция Items будет содержать актуальные данные
КоллекцияВходящие = Инбокс.Items;
Это решение позволяет избежать «ручного» запуска Outlook.exe и использования таймеров ожидания, что значительно повышает стабильность системы.
Если требуется принудительно запустить процесс «Отправить и получить» для всего профиля, мы можем воспользоваться коллекцией SyncObjects. В объекте Namespace содержатся группы синхронизации, определенные в настройках Outlook.
Выясним, как это реализовать на практике:
ПространствоИмен = Оутлук.GetNamespace("MAPI");
ГруппыСинхронизации = ПространствоИмен.SyncObjects;
// Запускаем синхронизацию для каждой группы (обычно это "Все учетные записи")
Для Номер = 1 По ГруппыСинхронизации.Count Цикл
ГруппыСинхронизации.Item(Номер).Start();
КонецЦикла;
Метод Start() инициирует асинхронный процесс обмена. Это более мощный инструмент, который гарантирует, что Outlook свяжется с сервером по всем протоколам.
Для того чтобы COM-объект работал корректно даже при закрытом приложении Outlook, крайне важно правильно инициализировать сессию. Рассмотрим использование метода Logon:
ПространствоИмен = Оутлук.GetNamespace("MAPI");
// Параметры: Профиль, Пароль, ПоказыватьДиалог, НоваяСессия
ПространствоИмен.Logon("Outlook", , Ложь, Истина);
Важные моменты:
NewSession = Истина гарантирует создание чистого программного сеанса.OUTLOOK.EXE не зависал в диспетчере задач:
Оутлук.Quit();
Оутлук = Неопределено;
Вместо постоянного опроса папки по таймеру, мы можем реализовать событийную модель. В Outlook существует событие NewMailEx, которое генерируется при поступлении нового сообщения. Это позволяет 1С обрабатывать почту в режиме реального времени.
Проанализируем алгоритм работы через события:
EntryID (уникальный идентификатор письма).GetItemFromID.Также можно использовать событие ItemAdd коллекции Items конкретной папки. Это особенно полезно, если письма сортируются правилами Outlook в разные папки еще на этапе получения.
Часто переход на MAPI обусловлен тем, что штатная ИнтернетПочта в 1С не всегда корректно обрабатывает флаги УведомитьОПрочтении. Однако, если вы решите вернуться к стандартным средствам 1С, стоит помнить о ручной установке заголовков.
Разберем, какие заголовки отвечают за уведомления:
В современных конфигурациях на базе БСП (Библиотеки стандартных подсистем) эти заголовки можно добавить в структуру ДополнительныеЗаголовки объекта ИнтернетПочтовоеСообщение. Если же вы остаетесь на MAPI, Outlook берет управление этими флагами на себя через свойства объекта MailItem: ReadReceiptRequested = Истина и OriginatorDeliveryReportRequested = Истина.
При попытке программного доступа к почте Outlook часто выводит окно безопасности: «Программа пытается получить доступ к адресам...». Выясним, как минимизировать эти прерывания:
Subject или Body, мы обращаемся к MAPI-тегам напрямую через схему http://schemas.microsoft.com/mapi/proptag/. Это зачастую позволяет «обмануть» защитный механизм Object Model Guard.Подводя итог, можно сказать, что связка 1С и Outlook через MAPI — это мощный инструмент. Главное — помнить о явном включении синхронизации через InAppFolderSyncObject или SyncObjects, корректном управлении COM-сессиями и использовании событийной модели для оптимизации производительности системы.