В процессе работы с 1С:Предприятием у пользователей часто возникает необходимость оперативно отправить сформированную печатную форму контрагенту или коллеге по электронной почте. Наиболее удобный сценарий — когда пользователь нажимает кнопку «Отправить» прямо в окне просмотра печатной формы, после чего автоматически открывается его привычный почтовый клиент (например, MS Outlook) с уже прикрепленным PDF-файлом. При этом пользователю остается лишь указать адресата и нажать кнопку отправки в самом почтовом клиенте.
В этой статье мы подробно разберем, как реализовать такой функционал в 1С 8.3. Мы рассмотрим как базовый вариант решения через COM-объект MS Outlook, так и профессиональные оптимизации: сохранение без временных файлов на диске, обход проблем с исчезновением подписи в письме, работу в управляемых формах и кроссплатформенные альтернативы.
Для реализации задачи нам необходимо решить две основные подзадачи:
Рассмотрим стандартный синтаксис платформы 1С для сохранения табличного документа. Начиная с версии 8.2, платформа умеет сохранять документы в PDF «из коробки», без использования сторонних виртуальных принтеров:
ТабличныйДокумент.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
Теперь объединим экспорт файла и работу с COM-объектом Outlook в единую процедуру. Разберем пример кода, который можно разместить, например, в модуле формы или в общем модуле:
Процедура ОтправитьПечатнуюФормуПочтой(ТабличныйДокумент) Экспорт
// 1. Определяем путь для временного файла
ПутьКФайлу = ПолучитьИмяВременногоФайла("pdf");
Попытка
// Сохраняем табличный документ в PDF формат
ТабличныйДокумент.Записать(ПутьКФайлу, ТипФайлаТабличногоДокумента.PDF);
Исключение
ВызватьИсключение "Не удалось сохранить печатную форму в PDF: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке());
КонецПопытки;
// 2. Инициализируем MS Outlook через COM-соединение
Попытка
Outlook = Новый COMОбъект("Outlook.Application");
Исключение
// Если Outlook не установлен или запуск заблокирован
Предупреждение("Не удалось запустить почтовый клиент MS Outlook. Проверьте, установлено ли приложение на вашем компьютере.");
Возврат;
КонецПопытки;
// 3. Создаем письмо и прикрепляем файл
Попытка
Письмо = Outlook.CreateItem(0); // 0 соответствует OlItemType.olMailItem
Письмо.Attachments.Add(ПутьКФайлу);
// Отображаем окно создания письма пользователю
Письмо.Display();
Исключение
Предупреждение("Ошибка при формировании почтового отправления в Outlook: " + КраткоеПредставлениеОшибки(ИнформацияОбОшибке()));
КонецПопытки;
// Примечание: Файл удалять сразу нельзя, так как Outlook может не успеть
// прочитать его до вызова метода Display(). Очистку временных файлов
// рекомендуется делать при закрытии формы или использовать альтернативные методы.
КонецПроцедуры
Этот код отлично решает базовую задачу. Однако на практике разработчики сталкиваются с рядом нюансов, которые могут сделать работу пользователей некомфортной или привести к ошибкам. Давайте разберем их и оптимизируем наше решение.
Часто программисты задаются вопросом: как обратиться к табличному документу, который уже выведен на экран пользователя, чтобы не формировать его заново? Использование глобальных переменных (как предложил автор темы в сообщении 21) — не самый лучший стиль разработки, так как это может привести к путанице при одновременном открытии нескольких печатных форм.
Правильнее обращаться к элементам активной формы напрямую. Рассмотрим, как это сделать в зависимости от типа интерфейса:
ТабДок = ЭлементыФормы.ПолеТабличногоДокумента;
ТабличныйДокумент, часто называемый Результат или ТабДок). Мы можем напрямую обратиться к этому реквизиту в коде формы:
ТабДок = ЭтотОбъект.Результат;
Таким образом, передав этот объект в нашу процедуру отправки, мы гарантированно работаем с тем содержимым, которое видит пользователь на своем экране.
Очень распространенная проблема при программном создании писем в Outlook: как только разработчик пытается заполнить текст письма программно (через свойства Письмо.Body или Письмо.HTMLBody), стандартная подпись пользователя (с логотипом компании, контактами и т.д.), настроенная в Outlook, бесследно исчезает.
Выясним причину: при создании нового письма Outlook автоматически генерирует HTML-код подписи и помещает его в свойство HTMLBody. Если мы перезаписываем это свойство напрямую, мы затираем подпись. Чтобы этого избежать, необходимо использовать правильный порядок действий:
Письмо.Display(). Это заставит Outlook сгенерировать письмо и подтянуть в него подпись пользователя.HTMLBody (которое уже содержит подпись).Посмотрим на пример реализации этого обхода:
Письмо = Outlook.CreateItem(0);
Письмо.Attachments.Add(ПутьКФайлу);
// Сначала отображаем письмо, чтобы Outlook вставил подпись по умолчанию
Письмо.Display();
// Теперь аккуратно внедряем наш текст перед подписью
ПриветственныйТекст = "Добрый день!<br>Во вложении находится направленный вам документ.<br><br>";
Письмо.HTMLBody = ПриветственныйТекст + Письмо.HTMLBody;
Благодаря этому нехитрому приему пользователь получит полностью готовое письмо со своим привычным оформлением подписи, и ему останется только нажать кнопку «Отправить».
Запись временных файлов на диск C:\Temp или через стандартную функцию ПолучитьИмяВременногоФайла() может вызвать сбои в корпоративных средах:
Современные версии платформы 1С 8.3 позволяют решить эту проблему изящно — путем сохранения табличного документа непосредственно в оперативную память через двоичные данные. Рассмотрим, как это сделать:
// Создаем поток в оперативной памяти
Поток = Новый ПотокВПамяти();
ТабличныйДокумент.Записать(Поток, ТипФайлаТабличногоДокумента.PDF);
// Получаем двоичные данные из потока памяти
ДвоичныеДанныеPDF = Поток.ЗакрытьИПолучитьДвоичныеДанные();
// Помещаем во временное хранилище для последующей передачи
АдресВХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанныеPDF, Новый УникальныйИдентификатор);
Полученные двоичные данные из временного хранилища можно передать на сервер для отправки через встроенный почтовый клиент 1С (без использования COM и Outlook), что полностью решает проблему локальных файлов.
Использование COM-технологии (COMОбъект("Outlook.Application")) имеет серьезные ограничения:
Если в вашей компании активно используются альтернативные операционные системы или веб-клиент, рекомендуется использовать встроенную подсистему БСП (Библиотека Стандартных Подсистем) «Электронная почта».
При использовании БСП отправка выглядит максимально кроссплатформенно:
Такой подход гарантирует стабильную работу системы на любых устройствах (включая планшеты и смартфоны) и полностью исключает зависимость от внешних почтовых программ и операционных систем.
Мы подробно разобрали, как быстро и просто настроить интеграцию 1С 8.3 с MS Outlook для отправки печатных форм в формате PDF. Для простых локальных баз на Windows отлично подойдет решение через COM-объект с обязательным соблюдением последовательности вызова Display() для сохранения подписи. Для крупных распределенных систем и кроссплатформенных сред лучшим выбором станет использование встроенной почты БСП и механизмов работы с двоичными данными в памяти.