Как правильно отправлять несколько отдельных писем в цикле через почтовый клиент 1С?

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

При разработке функционала рассылки уведомлений в 1С:Предприятие 8.3 начинающие разработчики часто сталкиваются с ситуацией, когда вместо нескольких разных писем программа отправляет одно письмо, в котором «склеены» данные всех предыдущих документов, либо корректно отправляется только последнее сообщение. В этой статье мы подробно разберем, почему возникает такая ошибка, и как правильно организовать работу с почтовым клиентом в коде.

Анализ проблемы: почему тексты «склеиваются»?

Рассмотрим ситуацию, представленную в вопросе. Автор использует цикл Пока Выборка.Следующий() Цикл, внутри которого наполняет объект Сообщение данными. Проблема заключается в том, что объект Сообщение (тип ИнтернетПочтовоеСообщение) создается один раз до начала цикла. Внутри цикла к нему применяются методы:


Сообщение.Тексты.Добавить(Текст);
Сообщение.Получатели.Добавить("example@mail.ru");

В 1С коллекции Тексты и Получатели работают по принципу дополнения. Если мы не очищаем их на каждой итерации, то при второй итерации в письме будет два текста и два получателя, при третьей — три, и так далее. Именно поэтому в почтовом ящике оказывается «каша» из данных всех документов. Выясним, как это исправить.

Решение №1: Принудительная очистка коллекций (быстрый способ)

Самый простой способ, который помог автору темы, — это вызов метода Очистить() для всех коллекций объекта сообщения в начале или в конце каждой итерации цикла. Это позволяет использовать один и тот же экземпляр объекта, предварительно удаляя из него данные предыдущего шага.

Разберем, как должен выглядеть модифицированный фрагмент кода:


Пока Выборка.Следующий() Цикл
    // Формируем текст сообщения
    ТекстПисьма = "Данные документа: " + Выборка.Ссылка;
    
    // ОЧИЩАЕМ коллекции перед заполнением
    Сообщение.Тексты.Очистить();
    Сообщение.Получатели.Очистить();
    
    // Теперь добавляем новые данные
    Сообщение.Тема = "Уведомление по документу " + Выборка.Номер;
    Сообщение.Тексты.Добавить(ТекстПисьма);
    Сообщение.Получатели.Добавить(Выборка.Email);
    
    // Отправляем
    Почта.Послать(Сообщение);
КонецЦикла;

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

Решение №2: Переинициализация объекта сообщения (рекомендуемый способ)

С точки зрения архитектуры 1С и «чистоты» кода, более правильным считается создание нового объекта ИнтернетПочтовоеСообщение внутри цикла. Это гарантирует, что никакие свойства (вложения, скрытые копии, специфические заголовки) не «перетекут» из старого сообщения в новое.

Рассмотрим пример реализации:


Пока Выборка.Следующий() Цикл
    // Создаем НОВЫЙ объект сообщения на каждой итерации
    НовоеСообщение = Новый ИнтернетПочтовоеСообщение;
    НовоеСообщение.Тема = "Тема письма";
    
    // Заполняем данными
    НовоеСообщение.Тексты.Добавить(ТекстДляТекущейСтроки);
    НовоеСообщение.Получатели.Добавить(АдресПолучателя);
    
    Попытка
        Почта.Послать(НовоеСообщение);
    Исключение
        Сообщить("Не удалось отправить письмо для: " + АдресПолучателя);
    КонецПопытки;
КонецЦикла;

Этот подход избавляет разработчика от необходимости вручную следить за очисткой каждой коллекции объекта.

Решение №3: Групповая отправка через массив писем (оптимизация)

Если документов очень много, отправка каждого письма отдельной командой Послать() может работать медленно, так как для каждого письма происходит отдельное взаимодействие с сервером. Метод ИнтернетПочта.Послать() позволяет передавать массив сообщений за один раз.

Проанализируем алгоритм групповой отправки:

  1. Создаем пустой Массив сообщений перед началом цикла.
  2. Внутри цикла создаем объекты ИнтернетПочтовоеСообщение, заполняем их и добавляем в массив.
  3. После завершения цикла один раз вызываем Почта.Послать(МассивСообщений).

Пример кода для оптимизированной отправки:


МассивПисем = Новый Массив;

Пока Выборка.Следующий() Цикл
    Письмо = Новый ИнтернетПочтовоеСообщение;
    Письмо.Тема = "Отчет от " + ТекущаяДата();
    Письмо.Тексты.Добавить("Текст сообщения...");
    Письмо.Получатели.Добавить("user@test.ru");
    
    МассивПисем.Добавить(Письмо);
КонецЦикла;

Если МассивПисем.Количество() > 0 Тогда
    Почта.Послать(МассивПисем);
КонецЕсли;

Дополнительные технические нюансы работы с ИнтернетПочтой

Чтобы ваш почтовый клиент работал стабильно, разберем еще несколько критически важных моментов, которые часто упускают новички.

1. Настройка SSL и портов. Современные почтовые сервисы (Mail.ru, Yandex, Gmail) требуют обязательного шифрования. В объекте ИнтернетПочтовыйПрофиль обязательно укажите:

2. Форматирование текста (HTML). Чтобы письмо выглядело профессионально, используйте HTML-разметку. Для этого при добавлении текста указывайте второй параметр:

Сообщение.Тексты.Добавить(ТекстHTML, ТипТекстаПочтовогоСообщения.HTML);

3. Кодировка. Для исключения проблем с отображением кириллицы в разных почтовых клиентах (Outlook, Gmail, мобильные приложения), рекомендуется явно устанавливать кодировку сообщения:

Сообщение.Кодировка = "UTF-8";

4. Обработка ошибок. Всегда заключайте блок отправки в конструкцию Попытка...Исключение. В случае ошибки в цикле (например, из-за неверного формата e-mail одного из контрагентов) программа может аварийно завершиться, и остальные адресаты не получат свои письма. Используйте логирование ошибок в отдельный текстовый файл или в Журнал Регистрации.

Таким образом, мы выяснили, что для корректной работы почтового клиента в 1С необходимо либо тщательно очищать коллекции объекта сообщения, либо (что предпочтительнее) создавать новый объект сообщения на каждом шаге цикла. Это обеспечит чистоту данных и надежность работы вашей системы уведомлений.

← На главную