Как отправить печатную форму в PDF формате из 1С 8.3 через Outlook?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

В процессе работы с 1С:Предприятием у пользователей часто возникает необходимость оперативно отправить сформированную печатную форму контрагенту или коллеге по электронной почте. Наиболее удобный сценарий — когда пользователь нажимает кнопку «Отправить» прямо в окне просмотра печатной формы, после чего автоматически открывается его привычный почтовый клиент (например, MS Outlook) с уже прикрепленным PDF-файлом. При этом пользователю остается лишь указать адресата и нажать кнопку отправки в самом почтовом клиенте.

В этой статье мы подробно разберем, как реализовать такой функционал в 1С 8.3. Мы рассмотрим как базовый вариант решения через COM-объект MS Outlook, так и профессиональные оптимизации: сохранение без временных файлов на диске, обход проблем с исчезновением подписи в письме, работу в управляемых формах и кроссплатформенные альтернативы.

Базовый алгоритм: экспорт в PDF и отправка через COM-объект

Для реализации задачи нам необходимо решить две основные подзадачи:

  1. Преобразовать сформированный табличный документ (печатную форму) в файл формата PDF и сохранить его на диске.
  2. Инициировать сессию с почтовым клиентом MS Outlook через COM-соединение, создать новое письмо, прикрепить полученный PDF-файл и вывести письмо на экран пользователя.

Рассмотрим стандартный синтаксис платформы 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(). Очистку временных файлов 
    // рекомендуется делать при закрытии формы или использовать альтернативные методы.
    
КонецПроцедуры

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

Проблема 1: Как динамически получить печатную форму с экрана?

Часто программисты задаются вопросом: как обратиться к табличному документу, который уже выведен на экран пользователя, чтобы не формировать его заново? Использование глобальных переменных (как предложил автор темы в сообщении 21) — не самый лучший стиль разработки, так как это может привести к путанице при одновременном открытии нескольких печатных форм.

Правильнее обращаться к элементам активной формы напрямую. Рассмотрим, как это сделать в зависимости от типа интерфейса:

Таким образом, передав этот объект в нашу процедуру отправки, мы гарантированно работаем с тем содержимым, которое видит пользователь на своем экране.

Проблема 2: Исчезновение стандартной подписи Outlook при заполнении тела письма

Очень распространенная проблема при программном создании писем в Outlook: как только разработчик пытается заполнить текст письма программно (через свойства Письмо.Body или Письмо.HTMLBody), стандартная подпись пользователя (с логотипом компании, контактами и т.д.), настроенная в Outlook, бесследно исчезает.

Выясним причину: при создании нового письма Outlook автоматически генерирует HTML-код подписи и помещает его в свойство HTMLBody. Если мы перезаписываем это свойство напрямую, мы затираем подпись. Чтобы этого избежать, необходимо использовать правильный порядок действий:

  1. Сначала вызываем метод Письмо.Display(). Это заставит Outlook сгенерировать письмо и подтянуть в него подпись пользователя.
  2. Считываем текущее содержимое HTMLBody (которое уже содержит подпись).
  3. Добавляем свой текст в начало считанного HTML-кода и записываем обратно.

Посмотрим на пример реализации этого обхода:


Письмо = Outlook.CreateItem(0);
Письмо.Attachments.Add(ПутьКФайлу);

// Сначала отображаем письмо, чтобы Outlook вставил подпись по умолчанию
Письмо.Display();

// Теперь аккуратно внедряем наш текст перед подписью
ПриветственныйТекст = "Добрый день!<br>Во вложении находится направленный вам документ.<br><br>";
Письмо.HTMLBody = ПриветственныйТекст + Письмо.HTMLBody;

Благодаря этому нехитрому приему пользователь получит полностью готовое письмо со своим привычным оформлением подписи, и ему останется только нажать кнопку «Отправить».

Проблема 3: Избавление от временных файлов на диске (работа через оперативную память)

Запись временных файлов на диск C:\Temp или через стандартную функцию ПолучитьИмяВременногоФайла() может вызвать сбои в корпоративных средах:

Современные версии платформы 1С 8.3 позволяют решить эту проблему изящно — путем сохранения табличного документа непосредственно в оперативную память через двоичные данные. Рассмотрим, как это сделать:


// Создаем поток в оперативной памяти
Поток = Новый ПотокВПамяти();
ТабличныйДокумент.Записать(Поток, ТипФайлаТабличногоДокумента.PDF);

// Получаем двоичные данные из потока памяти
ДвоичныеДанныеPDF = Поток.ЗакрытьИПолучитьДвоичныеДанные();

// Помещаем во временное хранилище для последующей передачи
АдресВХранилище = ПоместитьВоВременноеХранилище(ДвоичныеДанныеPDF, Новый УникальныйИдентификатор);

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

Кроссплатформенная альтернатива: отказ от COM-объектов

Использование COM-технологии (COMОбъект("Outlook.Application")) имеет серьезные ограничения:

Если в вашей компании активно используются альтернативные операционные системы или веб-клиент, рекомендуется использовать встроенную подсистему БСП (Библиотека Стандартных Подсистем) «Электронная почта».

При использовании БСП отправка выглядит максимально кроссплатформенно:

  1. Программа формирует печатную форму и сохраняет её в двоичные данные PDF.
  2. Вызывается встроенная форма создания письма 1С, куда файл передается как вложение.
  3. Письмо отправляется через системную учетную запись SMTP/IMAP напрямую с сервера 1С.

Такой подход гарантирует стабильную работу системы на любых устройствах (включая планшеты и смартфоны) и полностью исключает зависимость от внешних почтовых программ и операционных систем.

Резюме

Мы подробно разобрали, как быстро и просто настроить интеграцию 1С 8.3 с MS Outlook для отправки печатных форм в формате PDF. Для простых локальных баз на Windows отлично подойдет решение через COM-объект с обязательным соблюдением последовательности вызова Display() для сохранения подписи. Для крупных распределенных систем и кроссплатформенных сред лучшим выбором станет использование встроенной почты БСП и механизмов работы с двоичными данными в памяти.

← На главную