Как программно отправить печатную форму в формате PDF по электронной почте в 1С?

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

В процессе разработки часто возникает задача автоматической отправки печатных форм документов клиентам. Самым популярным форматом для этого является PDF. Однако при попытке программной реализации этой задачи разработчики сталкиваются с техническими трудностями: либо с правами доступа к файловой системе, либо с блокировками файлов, из-за которых их невозможно корректно удалить после отправки.

Давайте разберем, как правильно реализовать процесс формирования и отправки PDF-вложений, чтобы избежать ошибок блокировки ресурсов.

Решение через временные файлы

Самый распространенный способ — сохранение табличного документа во временный файл. Основная проблема здесь заключается в том, что система может «удерживать» файл заблокированным до тех пор, пока объект почтового сообщения не будет выгружен из памяти.

Для корректной работы выполним следующие действия:

  1. Сформируем уникальное имя файла во временном каталоге.
  2. Сохраним документ методом Записать.
  3. Добавим файл во вложения сообщения.
  4. После отправки сообщения явно очистим переменную с объектом почты и удалим файл.

Рассмотрим пример кода:


// Получаем путь к временному файлу
ИмяФайла = ПолучитьИмяВременногоФайла("pdf");

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

// Формируем почтовое сообщение
ПочтовоеСообщение = Новый ИнтернетПочтовоеСообщение;
ПочтовоеСообщение.Вложения.Добавить(ИмяФайла, "Счет.pdf");

// Отправляем
Почта = Новый ИнтернетПочта;
Почта.Подключиться(Профиль);
Почта.Послать(ПочтовоеСообщение);
Почта.Отключиться();

// Важный этап: очистка ресурсов
ПочтовоеСообщение = Неопределено; 
УдалитьФайлы(ИмяФайла);

Если файл все равно не удаляется, скорее всего, объект ИнтернетПочтовоеСообщение продолжает ссылаться на дескриптор файла. Присвоение переменной значения Неопределено помогает сборщику мусора освободить ресурсы.

Решение через потоки и двоичные данные

Более прогрессивный метод, позволяющий избежать записи на диск, — работа с объектом ДвоичныеДанные. Этот подход исключает конфликт блокировок на уровне операционной системы.

При использовании ПотокВПамяти (MemoryStream) важно помнить одну особенность: после записи данных в поток указатель (позиция) находится в конце. Перед тем как считать содержимое, необходимо сбросить позицию в начало.

Алгоритм действий:

  1. Создаем ПотокВПамяти.
  2. Записываем в него ТабличныйДокумент.
  3. Сбрасываем позицию потока.
  4. Получаем ДвоичныеДанные и добавляем их во вложение напрямую, минуя файловую систему.

Пример реализации без использования диска:


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

// Сбрасываем позицию потока в начало
Поток.УстановитьПозицию(0);

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

// Добавляем вложение в почту
ПочтовоеСообщение.Вложения.Добавить(ДвоичныеДанныеPDF, "Счет.pdf");

Рекомендации по оптимизации

Если ваша задача подразумевает отправку большого количества писем в цикле, рекомендуем придерживаться следующих правил:

Использование ДвоичныхДанных в оперативной памяти является предпочтительным способом, так как он делает ваше решение независимым от настроек прав доступа сервера и ограничений файловой системы, что делает код более отказоустойчивым и переносимым между различными средами (файловый вариант или клиент-серверный).

← На главную