Рассылка документов — это одна из наиболее востребованных функций в любой корпоративной системе. Часто возникает ситуация, когда у разработчика уже есть код для отправки одного письма, но требуется масштабировать его на весь реестр контрагентов. В рамках данной статьи мы разберем, как правильно организовать массовую рассылку, избежать типичных ошибок «зависания» интерфейса и корректно использовать возможности типовых конфигураций.
Проанализируем типичную ситуацию. Начинающие разработчики часто пытаются добавить всех получателей в одно письмо. Это допустимо, если вы отправляете общее объявление. Однако, если задача стоит в отправке индивидуальных реестров или актов каждому контрагенту, архитектура кода должна измениться. Разберем по шагам: объект письма ИнтернетПочтовоеСообщение должен создаваться заново на каждой итерации цикла по контрагентам.
Рассмотрим пример кода, который необходимо реализовать для обхода списка получателей:
Для Каждого СтрокаРеестра Из РезультатЗапроса Цикл
// Создаем новое сообщение для каждого контрагента
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Тема = "Реестр документов для " + СтрокаРеестра.КонтрагентНаименование;
// Добавляем адрес получателя (их может быть несколько через запятую)
МассивАдресов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтрокаРеестра.Email, ",");
Для Каждого Адрес Из МассивАдресов Цикл
Сообщение.Получатели.Добавить(СтрШаблон(Адрес));
КонецЦикла;
// Формируем вложение (табличный документ)
ТабДок = СформироватьПечатнуюФорму(СтрокаРеестра.КонтрагентСсылка);
ИмяФайла = ПолучитьИмяВременногоФайла("pdf");
ТабДок.Записать(ИмяФайла, ТипФайлаТабличногоДокумента.PDF);
// Добавляем вложение в сообщение
Сообщение.Вложения.Добавить(ИмяФайла, "Реестр.pdf");
// Отправляем конкретное письмо
Почта.Послать(Сообщение);
// Удаляем временный файл
УдалитьФайлы(ИмяФайла);
КонецЦикла;
Если вы работаете в современной типовой конфигурации (УТ 11, БП 3.0, ERP), мы крайне не рекомендуем использовать низкоуровневый объект ИнтернетПочта напрямую. Проанализируем преимущества Библиотеки Стандартных Подсистем (БСП). В ней реализован мощный механизм РаботаСПочтовымиСообщениями, который берет на себя хранение учетных записей, логирование и корректную обработку ошибок.
Рассмотрим, как будет выглядеть отправка через метод БСП:
ПараметрыОтправки = Новый Структура;
ПараметрыОтправки.Вставить("Кому", СтрокаРеестра.Email);
ПараметрыОтправки.Вставить("Тема", "Ваш реестр документов");
ПараметрыОтправки.Вставить("Тело", "Добрый день! Во вложении ваш актуальный реестр.");
// Формируем структуру вложения
Вложение = Новый Структура("Представление, Данные", "Реестр.pdf", ДвоичныеДанныеФайла);
МассивВложений = Новый Массив;
МассивВложений.Добавить(Вложение);
ПараметрыОтправки.Вставить("Вложения", МассивВложений);
// Отправка через БСП
РаботаСПочтовымиСообщениями.ОтправитьПочтовоеСообщение(УчетнаяЗапись, ПараметрыОтправки);
Выясним причину, почему это лучше: использование БСП позволяет письмам автоматически сохраняться в системе как объекты ЭлектронноеПисьмоИсходящее. Это значит, что менеджеры смогут увидеть историю переписки прямо в карточке контрагента, чего не произойдет при «прямой» отправке через встроенный язык.
Массовая рассылка — процедура длительная. Если в реестре 100 и более контрагентов, программа «замрет» для пользователя до завершения последнего процесса отправки. Чтобы избежать этого, разберем технологию фонового выполнения.
ФоновыеЗадания.Выполнить().Проанализируем ситуацию: что произойдет, если на 15-м письме из 100 произойдет сбой связи или будет указан неверный email? Без обработки исключений вся рассылка прервется. Выясним, как сделать код надежным.
Обязательно используйте конструкцию Попытка ... Исключение внутри цикла. Это позволит системе пропустить проблемного контрагента и продолжить работу с остальными. Также полезно добавить небольшую паузу между письмами (1-2 секунды), чтобы почтовые сервера (например, Mail.ru или Yandex) не заблокировали вас за спам.
Для Каждого Строка Из Реестр Цикл
Попытка
ОтправитьПисьмо(Строка);
// Небольшая задержка для предотвращения спам-фильтров
Приостановить(1);
Исключение
ЗаписьЖурналаРегистрации("РассылкаПисем", УровеньЖурналаРегистрации.Ошибка, , ,
"Ошибка отправки для: " + Строка.Контрагент + " Текст: " + ОписаниеОшибки());
КонецПопытки;
КонецЦикла;
Таким образом, мы выяснили, что для реализации качественной рассылки «по одной кнопке» необходимо: организовать правильный цикл создания объектов сообщений, использовать штатные модули БСП для интеграции с историей взаимодействий и применять фоновые задания для комфортной работы пользователей.