Интеграция 1С с внешними почтовыми клиентами, такими как Microsoft Outlook, является классической задачей при автоматизации документооборота. Одной из главных трудностей при использовании COM-объекта Outlook.Application является сохранение стандартной подписи пользователя, которая настроена в почтовом клиенте. В этой статье мы подробно разберем, как программно создать письмо, добавить в него основной текст, вложения и при этом не «потерять» оформление подписи.
Самый простой и эффективный способ получить подпись в письме — позволить самому Outlook инициализировать ее. Когда мы создаем объект письма программно, он изначально пуст. Однако вызов метода Display() заставляет Outlook отрисовать окно письма, в которое автоматически подтягивается подпись по умолчанию.
Рассмотрим алгоритм действий: мы создаем письмо, выводим его пользователю, считываем уже сформированное тело письма (в котором уже есть подпись) и добавляем свой текст сверху. Проанализируем пример кода:
Попытка
Outlook = Новый COMОбъект("Outlook.Application");
Письмо = Outlook.CreateItem(0); // 0 - тип olMailItem
// Важно вызвать Display() до манипуляций с текстом
Письмо.Display();
// Получаем HTML-код подписи, который Outlook уже вставил
СтараяПодпись = Письмо.HTMLBody;
// Формируем новый текст письма
ТекстПисьма = "Добрый день! Высылаем вам необходимые документы.";
// Объединяем ваш текст и подпись
Письмо.HTMLBody = "<p>" + ТекстПисьма + "</p>" + СтараяПодпись;
// Добавляем получателей и тему
Письмо.Subject = "Документы по договору";
Письмо.Recipients.Add("client@mail.ru");
Исключение
Сообщить("Ошибка при создании письма: " + ОписаниеОшибки());
КонецПопытки;
Важный нюанс: если вы используете свойство Body (простой текст), Outlook может сбросить форматирование письма в Plain Text, и HTML-подпись с картинками превратится в набор строк или исчезнет. Поэтому всегда работайте через HTMLBody.
Бывают ситуации, когда письмо нужно отправить в фоновом режиме без открытия окна (без метода Display()). В этом случае нам придется самостоятельно найти файл подписи на диске. Подписи Outlook хранятся в профиле пользователя в формате HTML.
Разберем, как найти и прочитать этот файл. Обычно они располагаются по пути: C:\Users\%ИмяПользователя%\AppData\Roaming\Microsoft\Signatures.
ПутьКПодписи = "C:\Users\" + ИмяПользователя + "\AppData\Roaming\Microsoft\Signatures\МояПодпись.htm";
ТекстДок = Новый ТекстовыйДокумент;
// Используем кодировку Windows-1251 или UTF-8 в зависимости от файла
ТекстДок.Прочитать(ПутьКПодписи, КодировкаТекста.ANSI);
СодержимоеПодписи = ТекстДок.ПолучитьТекст();
Письмо = Outlook.CreateItem(0);
Письмо.HTMLBody = "<body>" + МойТекст + СодержимоеПодписи + "</body>";
Выясним причину, по которой часто вместо картинок в подписи отображаются «красные крестики». Это происходит потому, что в HTML-файле пути к изображениям указаны как относительные (например, в папке МояПодпись.files). Чтобы картинки отобразились у получателя, их необходимо либо внедрять через Base64, либо прикреплять к письму как вложения и использовать ссылку через Content-ID (CID).
Часто требуется отправить письмо не только основному адресу, но и поставить в копию руководителя или менеджера. Для этого мы можем использовать свойство CC или коллекцию Recipients. Посмотрим на правильную реализацию через объектную модель:
// Простой способ через строку (разделитель - точка с запятой)
Письмо.CC = "manager@company.com; boss@company.com";
// Более надежный способ через добавление объектов
НовыйПолучатель = Письмо.Recipients.Add("assistant@company.com");
НовыйПолучатель.Type = 2; // 1 - Кому (To), 2 - Копия (CC), 3 - Скрытая копия (BCC)
// Проверка адресов по адресной книге
Письмо.Recipients.ResolveAll();
Метод ResolveAll() крайне полезен: он заставляет Outlook проверить, существуют ли такие адреса в глобальном списке адресов или контактах, и подсвечивает их (как при ручном вводе).
Проанализируем ситуацию, когда код должен работать в регламентном задании на сервере. Outlook является интерактивным приложением и требует наличия рабочего стола пользователя. При запуске под учетной записью службы сервера 1С выполнение может «зависнуть» на строке Новый COMОбъект.
Рекомендации для серверного использования:
dcomcnfg нужно найти приложение Outlook Message Attachment и на вкладке «Удостоверение» (Identity) установить «Интерактивный пользователь» (The interactive user). Однако это сработает только если на сервере выполнен вход в систему под этой учетной записью.ИнтернетПочтовыйПрофиль и протокол SMTP. Это работает стабильнее и не требует установки Office на сервер.Также стоит помнить о системе безопасности Outlook (Guard Dog). При попытке программной отправки может появиться модальное окно: «Программа пытается отправить сообщение от вашего имени». Чтобы этого избежать, убедитесь, что на компьютере установлен и обновлен антивирус — в этом случае Outlook в «Центре управления безопасностью» позволяет разрешить программный доступ без предупреждений.
После того как письмо отправлено (метод Send()) или показано пользователю, необходимо корректно завершить работу с COM-объектами, чтобы в диспетчере задач не оставались «висящие» процессы outlook.exe.
Письмо = Неопределено;
// Если вы создавали объект Outlook только для этой операции и он не был запущен ранее:
// Outlook.Quit();
Outlook = Неопределено;
Помните, что использование Outlook.Quit() закроет приложение полностью. Если пользователь в этот момент работал в своей почте, это может привести к потере его данных, поэтому используйте этот метод с осторожностью, только если вы уверены, что создали процесс «с нуля».
Рассмотренные нами методы позволяют гибко управлять процессом создания писем. Сочетание автоматического вызова Display() для получения подписи и последующей программной модификации HTMLBody является «золотым стандартом» при разработке интеграции на стороне клиента.