При настройке массовых рассылок в 1С:Управление торговлей 11 программисты часто сталкиваются с неприятной ситуацией: тестовые письма приходят корректно, но при запуске полноценной рассылки по большому списку контрагентов содержимое письма заменяется строкой «Форматированный документ». Это происходит из-за особенностей работы платформы с одноименным объектом и механизмов его преобразования в HTML. В данной статье мы подробно разберем причины этой ошибки и рассмотрим пошаговые инструкции по её устранению.
Давайте проанализируем, почему 1С выводит именно этот текст. Объект ФорматированныйДокумент предназначен для хранения текста с оформлением и внедренными изображениями. Однако при отправке письма через объект ИнтернетПочтовоеСообщение, свойство Текст или HTMLТекст ожидает строковое значение.
Если в коде происходит неявное приведение типа (например, попытка передать сам объект вместо его содержимого) или если механизм автоматического преобразования дает сбой на стороне сервера, 1С подставляет строковое представление типа объекта. Это типичное поведение платформы: когда она не может корректно интерпретировать данные для вывода, она пишет название типа — «Форматированный документ».
Основные факторы, провоцирующие сбой при массовой отправке:
PNG) при формировании MIME-сообщения создает временный файл. При интенсивной рассылке система может не успевать освобождать ссылки на эти файлы.Рассмотрим самый надежный способ решения проблемы — программный вызов метода преобразования документа в HTML. Мы не должны полагаться на то, что платформа сама поймет, как отправить объект. Нам нужно подготовить строку HTML и коллекцию картинок (ресурсов) самостоятельно.
Проанализируем пример кода, который необходимо внедрить в цикл рассылки:
// Внутри цикла по получателям
Письмо = Новый ИнтернетПочтовоеСообщение;
ТекстHTML = "";
КартинкиПисьма = Новый Структура; // Сюда 1С положит картинки из документа
// Явно извлекаем HTML-код из объекта ФорматированныйДокумент
ОбъектФорматированныйДокумент.ПолучитьHTML(ТекстHTML, КартинкиПисьма);
// Настраиваем тело письма
ТелоПисьма = Письмо.Тексты.Добавить();
ТелоПисьма.ТипТекста = ТипТекстаПочтовогоСообщения.HTML;
ТелоПисьма.Текст = ТекстHTML;
// Важно: обрабатываем встроенные картинки (CID)
Для Каждого Картинка Из КартинкиПисьма Цикл
Вложение = Письмо.Вложения.Добавить(Картинка.Значение, Картинка.Ключ);
Вложение.Идентификатор = Картинка.Ключ; // Устанавливаем Content-ID
КонецЦикла;
// Отправка через установленное соединение
Соединение.Послать(Письмо);
Важный момент: Обратите внимание на использование Идентификатор для вложения. Это позволяет HTML-коду внутри письма ссылаться на картинку через src="cid:...". Без этого изображения в рассылке «отвалятся», а текст может снова превратиться в заглушку типа данных.
Выясним, почему задержка (Пауза), которую пробовал автор темы, не всегда помогает. Проблема чаще всего не в скорости SMTP-сервера, а в утечке памяти или блокировке ресурсов внутри сеанса 1С. При массовой рассылке (более 50-100 писем) необходимо принудительно обнулять объекты.
Рассмотрим правила «гигиены» кода в цикле:
Письмо и ОбъектФорматированныйДокумент в значение Неопределено.МенеджерВременныхФайлов, не забывайте очищать его, иначе каталог временных файлов сервера быстро переполнится уникальными именами картинок.SMTP-серверу (вызывать Соединение.Отключиться() и снова Подключиться()) каждые 100 писем. Это сбросит состояние сессии на почтовом сервере yandex.ru и предотвратит подозрения в спам-активности.Если вышеописанные методы не помогают на экстремально больших объемах (тысячи получателей), проанализируем альтернативный подход. Вместо использования тяжелого объекта ФорматированныйДокумент, мы можем формировать HTML текст письма напрямую, используя строковые функции или ЧтениеТекста.
Посмотрим на пример формирования шаблона:
ШаблонТекста = "<html><body>"
+ "<p>Добрый день, [ИмяКонтрагента]!</p>"
+ "<p>Ваш отчет во вложении.</p>"
+ "<img src=""cid:реклама_png"">"
+ "</body></html>";
ТекстПисьма = СтрЗаменить(ШаблонТекста, "[ИмяКонтрагента]", Выборка.Наименование);
// При такой схеме мы работаем только со строками,
// что исключает ошибку типа «Форматированный документ».
Этот метод гарантирует, что 1С не будет пытаться «умничать» при сериализации объектов, так как вы передаете в ИнтернетПочтовоеСообщение обычную строку. Картинку рекламы при этом нужно добавить во вложения один раз с фиксированным Идентификатор (например, "реклама_png").
Поскольку автор использует smtp.yandex.ru, стоит учитывать, что Яндекс может накладывать ограничения на объем передаваемых данных в рамках одной TCP-сессии. Если письмо содержит тяжелое вложение (отчет) и PNG-картинку, суммарный объем письма может превышать 1-2 Мб.
Проанализируем ситуацию: при отправке 500 писем по 2 Мб через одно соединение, объем трафика составит 1 Гб. Если в процессе передачи произойдет кратковременный разрыв соединения или сервер ответит Timeout, 1С может некорректно обработать исключение и попытаться отправить «пустое» сообщение или сообщение с ошибкой типа данных. Всегда используйте конструкцию Попытка...Исключение вокруг метода Соединение.Послать() и записывайте подробности ошибки в ЖурналРегистрации.
Резюмируем: Для исправления ошибки «Форматированный документ» необходимо перейти от передачи объекта к передаче явно сформированной HTML-строки, корректно обрабатывать CID встроенных изображений и следить за освобождением памяти в длительных циклах рассылки.