При разработке функционала рассылки уведомлений в 1С:Предприятие 8.3 начинающие разработчики часто сталкиваются с ситуацией, когда вместо нескольких разных писем программа отправляет одно письмо, в котором «склеены» данные всех предыдущих документов, либо корректно отправляется только последнее сообщение. В этой статье мы подробно разберем, почему возникает такая ошибка, и как правильно организовать работу с почтовым клиентом в коде.
Рассмотрим ситуацию, представленную в вопросе. Автор использует цикл Пока Выборка.Следующий() Цикл, внутри которого наполняет объект Сообщение данными. Проблема заключается в том, что объект Сообщение (тип ИнтернетПочтовоеСообщение) создается один раз до начала цикла. Внутри цикла к нему применяются методы:
Сообщение.Тексты.Добавить(Текст);
Сообщение.Получатели.Добавить("example@mail.ru");
В 1С коллекции Тексты и Получатели работают по принципу дополнения. Если мы не очищаем их на каждой итерации, то при второй итерации в письме будет два текста и два получателя, при третьей — три, и так далее. Именно поэтому в почтовом ящике оказывается «каша» из данных всех документов. Выясним, как это исправить.
Самый простой способ, который помог автору темы, — это вызов метода Очистить() для всех коллекций объекта сообщения в начале или в конце каждой итерации цикла. Это позволяет использовать один и тот же экземпляр объекта, предварительно удаляя из него данные предыдущего шага.
Разберем, как должен выглядеть модифицированный фрагмент кода:
Пока Выборка.Следующий() Цикл
// Формируем текст сообщения
ТекстПисьма = "Данные документа: " + Выборка.Ссылка;
// ОЧИЩАЕМ коллекции перед заполнением
Сообщение.Тексты.Очистить();
Сообщение.Получатели.Очистить();
// Теперь добавляем новые данные
Сообщение.Тема = "Уведомление по документу " + Выборка.Номер;
Сообщение.Тексты.Добавить(ТекстПисьма);
Сообщение.Получатели.Добавить(Выборка.Email);
// Отправляем
Почта.Послать(Сообщение);
КонецЦикла;
Важный момент: не забывайте очищать также коллекцию Вложения, если вы прикрепляете файлы, иначе каждый следующий получатель будет получать файлы всех предыдущих документов.
С точки зрения архитектуры 1С и «чистоты» кода, более правильным считается создание нового объекта ИнтернетПочтовоеСообщение внутри цикла. Это гарантирует, что никакие свойства (вложения, скрытые копии, специфические заголовки) не «перетекут» из старого сообщения в новое.
Рассмотрим пример реализации:
Пока Выборка.Следующий() Цикл
// Создаем НОВЫЙ объект сообщения на каждой итерации
НовоеСообщение = Новый ИнтернетПочтовоеСообщение;
НовоеСообщение.Тема = "Тема письма";
// Заполняем данными
НовоеСообщение.Тексты.Добавить(ТекстДляТекущейСтроки);
НовоеСообщение.Получатели.Добавить(АдресПолучателя);
Попытка
Почта.Послать(НовоеСообщение);
Исключение
Сообщить("Не удалось отправить письмо для: " + АдресПолучателя);
КонецПопытки;
КонецЦикла;
Этот подход избавляет разработчика от необходимости вручную следить за очисткой каждой коллекции объекта.
Если документов очень много, отправка каждого письма отдельной командой Послать() может работать медленно, так как для каждого письма происходит отдельное взаимодействие с сервером. Метод ИнтернетПочта.Послать() позволяет передавать массив сообщений за один раз.
Проанализируем алгоритм групповой отправки:
Массив сообщений перед началом цикла.ИнтернетПочтовоеСообщение, заполняем их и добавляем в массив.Почта.Послать(МассивСообщений).Пример кода для оптимизированной отправки:
МассивПисем = Новый Массив;
Пока Выборка.Следующий() Цикл
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Тема = "Отчет от " + ТекущаяДата();
Письмо.Тексты.Добавить("Текст сообщения...");
Письмо.Получатели.Добавить("user@test.ru");
МассивПисем.Добавить(Письмо);
КонецЦикла;
Если МассивПисем.Количество() > 0 Тогда
Почта.Послать(МассивПисем);
КонецЕсли;
Чтобы ваш почтовый клиент работал стабильно, разберем еще несколько критически важных моментов, которые часто упускают новички.
1. Настройка SSL и портов. Современные почтовые сервисы (Mail.ru, Yandex, Gmail) требуют обязательного шифрования. В объекте ИнтернетПочтовыйПрофиль обязательно укажите:
ИспользованиеSSLSMTP = Истина;ПортSMTP = 465;2. Форматирование текста (HTML). Чтобы письмо выглядело профессионально, используйте HTML-разметку. Для этого при добавлении текста указывайте второй параметр:
Сообщение.Тексты.Добавить(ТекстHTML, ТипТекстаПочтовогоСообщения.HTML);
3. Кодировка. Для исключения проблем с отображением кириллицы в разных почтовых клиентах (Outlook, Gmail, мобильные приложения), рекомендуется явно устанавливать кодировку сообщения:
Сообщение.Кодировка = "UTF-8";
4. Обработка ошибок. Всегда заключайте блок отправки в конструкцию Попытка...Исключение. В случае ошибки в цикле (например, из-за неверного формата e-mail одного из контрагентов) программа может аварийно завершиться, и остальные адресаты не получат свои письма. Используйте логирование ошибок в отдельный текстовый файл или в Журнал Регистрации.
Таким образом, мы выяснили, что для корректной работы почтового клиента в 1С необходимо либо тщательно очищать коллекции объекта сообщения, либо (что предпочтительнее) создавать новый объект сообщения на каждом шаге цикла. Это обеспечит чистоту данных и надежность работы вашей системы уведомлений.