Как программно прикрепить файл к исходящему письму в 1С 8.3

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

В процессе разработки в среде 1С:Предприятие 8.3 (особенно в конфигурациях на базе БСП, таких как ERP 2.4/2.5, УТ 11 или КА 2) часто возникает задача: программно сформировать печатную форму (например, счет на оплату в формате PDF с QR-кодом) и автоматически прикрепить её к новому исходящему электронному письму — для этого есть готовая автоматическая рассылка печатных форм и файлов по email. На первый взгляд задача кажется простой, но разработчики часто сталкиваются с тем, что файлы во вложениях оказываются «битыми» или имеют размер 1 КБ.

В этой статье мы подробно разберем, как правильно реализовать этот механизм, рассмотрим типичные ошибки и проанализируем несколько способов решения — от использования стандартных функций Библиотеки Стандартных Подсистем (БСП) до прямой отправки через почтовый протокол.

Почему возникают ошибки при ручном заполнении справочников?

Рассмотрим ситуацию, с которой часто начинают разработчики: попытка вручную создать элемент в справочнике ЭлектронноеПисьмоИсходящееПрисоединенныеФайлы. Проблема заключается в том, что в современных конфигурациях механизмы хранения файлов значительно усложнились. Файлы могут храниться как в самой информационной базе (в реквизите типа ХранилищеЗначения), так и в томах на диске.

Если мы просто записываем двоичные данные в реквизит, но не учитываем настройки системы (например, хранение в томах), 1С может создать «пустую» карточку файла. В результате при попытке открыть вложение из письма пользователь увидит ошибку доступа или нечитаемый файл. Чтобы избежать этого, крайне рекомендуется использовать программный интерфейс БСП. Для оптимизации места хранения писем и вложений есть перенос хранения файлов и вложений в тома на диске.

Способ 1. Использование универсального механизма БСП «Работа с файлами»

Это наиболее правильный и надежный метод для конфигураций ERP, УТ и КА — для них отлично подойдёт готовое автоматическое создание и массовая рассылка актов сверки. Мы делегируем системе всю работу по определению места хранения, расчету размера файла и установке метаданных.

Разберем процесс по шагам. Сначала сформируем печатную форму и сохраним её во временный каталог на сервере:


// 1. Формируем табличный документ (например, счет на оплату)
ТабличныйДокумент = Обработки.ПечатьСчетовНаОплату.СформироватьПечатнуюФормуСчетНаОплату(ОбъектыПечати);

// 2. Определяем путь во временном каталоге
ИмяФайлаПДФ = "Счет_на_оплату.pdf";
ПутьПДФ = КаталогВременныхФайлов() + ИмяФайлаПДФ;

// Важно: настраиваем масштаб, чтобы PDF не "съехал"
ТабличныйДокумент.АвтоМасштаб = Истина;
ТабличныйДокумент.Записать(ПутьПДФ, ТипФайлаТабличногоДокумента.PDF);

Теперь, когда файл физически существует на диске сервера, воспользуемся функцией РаботаСФайлами.ДобавитьФайл. Этот метод создаст запись в справочнике присоединенных файлов и свяжет её с вашим письмом:


ПараметрыФайла = Новый Структура;
// Ссылка на объект-владелец (наше исходящее письмо)
ПараметрыФайла.Вставить("ВладелецФайлов", ЭлПисьмо.Ссылка); 
ПараметрыФайла.Вставить("Автор", Пользователи.ТекущийПользователь());
ПараметрыФайла.Вставить("ИмяБезРасширения", "Счет на оплату");
ПараметрыФайла.Вставить("РасширениеБезТочки", "pdf");
ПараметрыФайла.Вставить("ВремяИзмененияУниверсальное", ТекущаяДата());

// Добавляем файл в систему
РаботаСФайлами.ДобавитьФайл(ПараметрыФайла, ПутьПДФ, , "Создан автоматически");

Преимущество этого метода: БСП самостоятельно проверит права доступа, определит тип хранения (база или тома) и корректно заполнит все служебные реквизиты. Нам не нужно заботиться о создании ХранилищеЗначения вручную.

Способ 2. Отправка письма «на лету» без создания карточек файлов

Иногда задача стоит иначе: нужно просто отправить письмо программно, не сохраняя его в справочниках 1С (или используя письмо только как контейнер для отправки). В этом случае удобнее использовать модуль РаботаСПочтовымиСообщениями. Для этой задачи есть модуль автоматической отправки документов и вложений по email.

Проанализируем пример функции, которая принимает адрес файла во временном хранилище и отправляет его в качестве вложения:


Функция ОтправитьПисьмоСВложением(ПочтаПолучателя, Тема, Текст, ИмяФайла, АдресХранилища)
    
    УчетнаяЗапись = Справочники.УчетныеЗаписиЭлектроннойПочты.СистемнаяУчетнаяЗаписьЭлектроннойПочты;
    
    // Формируем структуру вложений
    Вложения = Новый Массив;
    ОписаниеВложения = Новый Структура("Представление, АдресВоВременномХранилище", ИмяФайла, АдресХранилища);
    Вложения.Добавить(ОписаниеВложения);
    
    ПараметрыПисьма = Новый Структура;
    ПараметрыПисьма.Вставить("Кому", ПочтаПолучателя);
    ПараметрыПисьма.Вставить("Тема", Тема);
    ПараметрыПисьма.Вставить("Тело", Текст);
    ПараметрыПисьма.Вставить("ТипТекста", "ПростойТекст");
    ПараметрыПисьма.Вставить("Вложения", Вложения);
    
    Попытка
        Результат = РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(УчетнаяЗапись, ПараметрыПисьма);
        Возврат ЗначениеЗаполнено(Результат);
    Исключение
        ЗаписьЖурналаРегистрации("ОтправкаПочты", УровеньЖурналаРегистрации.Ошибка, , , ОписаниеОшибки());
        Возврат Ложь;
    КонецПопытки;
    
КонецФункции

Обратите внимание на параметр АдресВоВременномХранилище. Перед вызовом этой функции файл нужно поместить в хранилище с помощью метода ПоместитьВоВременноеХранилище(Новый ДвоичныеДанные(ПутьКФайлу)). Это критически важно при работе на сервере, так как данные передаются между контекстами выполнения.

Способ 3. Прямая работа с объектом ИнтернетПочтовоеСообщение

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

Рассмотрим пример добавления вложения напрямую из файла на диске:


Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Тема = "Ваш счет на оплату";

// Добавляем вложение напрямую через ДвоичныеДанные
// Система сама извлечет данные из файла и упакует их в MIME-сообщение
ДанныеФайла = Новый ДвоичныеДанные(ПутьПДФ);
Сообщение.Вложения.Добавить(ДанныеФайла, "Invoice.pdf");

// Далее следует стандартный цикл отправки через ИнтернетПочта.Послать()

Важные нюансы и рекомендации

При реализации автоматической отправки файлов стоит учитывать несколько технических моментов, которые часто упускаются из виду:

  1. Жизненный цикл временных файлов: После того как файл был записан в справочник присоединенных файлов или отправлен, не забывайте удалять временный файл с диска с помощью команды УдалитьФайлы(ПутьПДФ). Это предотвратит переполнение дискового пространства сервера.
  2. Установка шрифтов: Если ваш сервер 1С работает под управлением Linux, убедитесь, что в системе установлены шрифты (например, шрифты Microsoft), иначе сформированный PDF может содержать нечитаемые символы («квадраты») или иметь некорректную верстку.
  3. Лимиты вложений: В настройках 1С (системные настройки почты) часто установлены ограничения на размер вложения (например, 10 или 20 МБ). Если ваш файл превышает этот лимит, письмо может уйти без вложения или вовсе заблокироваться. Всегда проверяйте Размер объекта Файл перед прикреплением.
  4. Блокировки ОС: Иногда после метода ТабличныйДокумент.Записать() операционная система не успевает мгновенно освободить файл. Если следующая строка кода пытается его прочитать, может возникнуть ошибка доступа. В критических местах можно добавить проверку Файл.Существует() или небольшую паузу.

Подводя итог, можно сказать, что для современных конфигураций лучшим решением является использование метода РаботаСФайлами.ДобавитьФайл. Это гарантирует корректную работу со всеми подсистемами 1С и избавляет разработчика от необходимости знать внутреннюю структуру таблиц хранения данных. Для настройки регулярной рассылки документов клиентам подойдёт обработка регулярной отправки счетов и УПД по email.

← На главную