При разработке внешних обработок часто возникает задача автоматической отправки документов или бланков по электронной почте. Чтобы не хранить файлы на диске и не зависеть от внешних путей, наиболее удобным способом является использование макетов типа Двоичные данные. В этой статье мы разберем, как правильно извлечь файл из макета, подготовить его и прикрепить к электронному письму, используя механизмы Библиотеки стандартных подсистем (БСП).
Рассмотрим ситуацию, с которой часто сталкиваются разработчики. При попытке получить данные из макета программный код может выглядеть следующим образом:
// Ошибочный вариант
Заявление = Новый ДвоичныеДанные(ЭтотОбъект.ПолучитьМакет("Заявление"));
Проанализируем причину ошибки. Метод ПолучитьМакет() для макета, имеющего тип Двоичные данные, уже возвращает объект типа ДвоичныеДанные. Конструктор Новый ДвоичныеДанные(), в свою очередь, ожидает на вход путь к файлу на диске (строку). Когда мы передаем в этот конструктор уже готовый объект данных, система пытается интерпретировать содержимое файла как путь, что приводит к ошибке «Файл не обнаружен» или некорректному чтению данных.
Правильный способ получения данных из макета выглядит так:
// Правильный вариант
Заявление = ЭтотОбъект.ПолучитьМакет("Заявление");
Разберем по шагам процесс формирования вложения и отправки сообщения. В большинстве современных конфигураций 1С (УТ 11, БП 3.0, ERP) для работы с почтой используется программный интерфейс БСП, в частности общий модуль РаботаСПочтовымиСообщениями.
Шаг 1. Получение данных из макета.
Сначала мы извлекаем содержимое файла из состава обработки. Выясним, что если код выполняется внутри модуля обработки, мы используем ЭтотОбъект.
ДанныеФайла = ЭтотОбъект.ПолучитьМакет("МойМакетСДокументом");
Шаг 2. Помещение данных во временное хранилище.
Для передачи данных между сервером и процедурами отправки БСП рекомендуется использовать временное хранилище. Это позволяет избежать лишних операций записи на диск сервера.
АдресВоВременномХранилище = ПоместитьВоВременноеХранилище(ДанныеФайла, Новый УникальныйИдентификатор);
Шаг 3. Формирование структуры вложений.
БСП ожидает массив структур, описывающих вложения. Важно правильно указать имя файла с расширением, так как в самом макете эта информация не сохраняется в явном виде для метода отправки.
МассивВложений = Новый Массив;
СтруктураВложения = Новый Структура;
СтруктураВложения.Вставить("Представление", "Заявление_на_отпуск.doc"); // Имя, которое увидит получатель
СтруктураВложения.Вставить("АдресВоВременномХранилище", АдресВоВременномХранилище);
МассивВложений.Добавить(СтруктураВложения);
Шаг 4. Подготовка параметров и отправка.
Теперь соберем все параметры в структуру и вызовем метод отправки. Рассмотрим пример заполнения параметров:
ПараметрыОтправки = Новый Структура;
ПараметрыОтправки.Вставить("Кому", "user@example.com");
ПараметрыОтправки.Вставить("Тема", "Вложенный документ из 1С");
ПараметрыОтправки.Вставить("Тело", "Добрый день! Во вложении файл из макета.");
ПараметрыОтправки.Вставить("Вложения", МассивВложений);
// ПрофильЭП — это ссылка на учетную запись электронной почты в системе
РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(ПрофильЭП, ПараметрыОтправки);
Иногда возникают ситуации, когда внешние компоненты или старые процедуры обмена не поддерживают работу с временным хранилищем. В этом случае проанализируем ситуацию с сохранением данных на диск.
ДвоичныеДанные из макета.ПолучитьИмяВременногоФайла().Записать().Пример реализации этого подхода:
ДанныеМакета = ЭтотОбъект.ПолучитьМакет("Заявление");
ИмяФайла = ПолучитьИмяВременногоФайла("doc");
ДанныеМакета.Записать(ИмяФайла);
// ... здесь логика прикрепления файла по пути ИмяФайла ...
// После отправки очищаем за собой временные файлы
Попытка
УдалитьФайлы(ИмяФайла);
Исключение
ЗаписьЖурналаРегистрации("ОчисткаВременныхФайлов", УровеньЖурналаРегистрации.Предупреждение,,, "Не удалось удалить файл: " + ИмяФайла);
КонецПопытки;
Разберем несколько критически важных моментов, которые обеспечат стабильную работу вашего кода:
1. Контекст исполнения. Если вы работаете с внешней обработкой, помните, что на сервере объект обработки должен быть доступен. Если вы вызываете отправку из фонового задания, убедитесь, что макет извлекается корректно. Метод ПолучитьМакет() работает на сервере, что идеально подходит для регламентных операций.
2. Имена и расширения файлов. При хранении файла в макете 1С сохраняет только «сырые» байты. Система не знает, было ли это .pdf, .docx или .zip. Поэтому при формировании структуры вложения в поле Представление всегда явно указывайте расширение. Без него почтовый клиент получателя может не определить тип файла, и пользователь не сможет его открыть двойным кликом.
3. Объем памяти. Помещение больших файлов (десятки и сотни мегабайт) во временное хранилище или передача их как объектов ДвоичныеДанные нагружает оперативную память процесса rphost. Для очень тяжелых файлов метод с записью во временный файл на диске (описанный выше) может быть более предпочтительным, так как он снижает пиковую нагрузку на RAM сервера.
4. Уникальность идентификатора. При использовании ПоместитьВоВременноеХранилище рекомендуется вторым параметром передавать Новый УникальныйИдентификатор или идентификатор формы. Это гарантирует, что данные будут очищены системой автоматически после завершения сеанса или закрытия формы, предотвращая утечки памяти на сервере.
Таким образом, мы рассмотрели основной механизм работы с макетами типа Двоичные данные. Главный секрет успеха заключается в понимании того, что ПолучитьМакет() уже возвращает готовый к работе объект данных, который достаточно просто передать в почтовую подсистему.