Как разбить строку с несколькими e-mail адресами в массив и добавить получателей в почтовое сообщение в 1С?

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

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

Разберем по шагам различные варианты решения этой задачи, выясним причины типичных ошибок начинающих разработчиков и сформируем итоговый рабочий алгоритм.

Способ 1. Использование встроенной функции СтрРазделить (для платформы 8.3.6 и выше)

Начиная с версии платформы 8.3.6, в платформе 1С:Предприятие доступна штатная функция СтрРазделить(). Она работает на уровне платформы значительно быстрее любых программных алгоритмов обхода строк.

Посмотрим на синтаксис и базовый пример использования функции:


// Получаем строку с адресами
СтрокаАдресов = Контрагент.АдресЭлектроннойПочты;

// Разделяем строку по запятой
МассивАдресов = СтрРазделить(СтрокаАдресов, ",", Ложь);

// Обходим массив и выполняем действия с каждым адресом
Для Каждого Адрес Из МассивАдресов Цикл
    АдресОчищенный = СокрЛП(Адрес);
    Если Не ПустаяСтрока(АдресОчищенный) Тогда
        Сообщить(АдресОчищенный);
    КонецЕсли;
КонецЦикла;

Важные параметры функции СтрРазделить:

  1. Первый параметр — исходная строка для разделения.
  2. Второй параметр — символ или строка-разделитель (например, "," или ";").
  3. Третий параметр (необязательный) — значение типа Булево (Истина или Ложь), определяющее, нужно ли включать в результирующий массив пустые строки. Передача сюда строк или спецсимволов вроде Символы.ПС вызовет ошибку типа данных.

Способ 2. Использование функций Библиотеки стандартных подсистем (БСП)

Если база работает в режиме совместимости с версиями 8.3.5 и ниже, функция СтрРазделить() будет недоступна (вызовет ошибку компиляции «Процедура или функция с указанным именем не определена»). В конфигурациях на базе БСП для таких случаев предусмотрена функция общего модуля СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок.

Рассмотрим пример ее корректного вызова:


СтрокаАдресов = Контрагент.АдресЭлектроннойПочты;

// Третий параметр принимает Булево: ПропускатьПустыеСтроки
МассивАдресов = СтроковыеФункцииКлиентСервер.РазложитьСтрокуВМассивПодстрок(СтрокаАдресов, ",", Истина);

Для Каждого Адрес Из МассивАдресов Цикл
    АдресОчищенный = СокрЛП(Адрес);
    Сообщить(АдресОчищенный);
КонецЦикла;

Способ 3. Универсальный способ через СтрЗаменить и многострочный текст

Если конфигурация полностью самописная, в ней нет БСП, а режим совместимости старый, можно воспользоваться классическим методом преобразования строки в многострочный текст с последующим построчным чтением:


СтрокаАдресов = Контрагент.АдресЭлектроннойПочты;

// Заменяем разделитель на символ перевода строки
МногострочныйТекст = СтрЗаменить(СтрокаАдресов, ",", Символы.ПС);

ВсегоСтрок = СтрЧислоСтрок(МногострочныйТекст);
Для НомерСтроки = 1 По ВсегоСтрок Цикл
    ТекущийАдрес = СокрЛП(СтрПолучитьСтроку(МногострочныйТекст, НомерСтроки));
    Если Не ПустаяСтрока(ТекущийАдрес) Тогда
        Сообщить(ТекущийАдрес);
    КонецЕсли;
КонецЦикла;

Разбор типичных ошибок при работе со строками и почтой

Проанализируем частые ошибки, возникающие при реализации данной логики:

  1. Ошибка «Итератор для значения не определен» / синтаксические ошибки цикла:
    Конструкция цикла по коллекции пишется со служебным словом Из, а не В. Неправильно: Для Каждого Элемент В Массив Цикл.
    Правильно: Для Каждого Элемент Из Массив Цикл. Кроме того, переменная, по которой выполняется обход, обязательно должна быть коллекцией (массивом, списком значений, таблицей значений), а не простой строкой.
  2. Ошибка «Значение не является значением объектного типа (Получатели)»:
    Данная ошибка возникает, если обращение к свойству Сообщение.Получатели выполняется до того, как был создан сам объект сообщения (Новый ИнтернетПочтовоеСообщение). Инициализация объекта должна предшествовать заполнению его реквизитов.
  3. Некорректная отправка из-за пробелов в адресах:
    Если пользователи вводят адреса в виде "user1@test.ru, user2@test.ru", то после разделения по запятой второй адрес будет содержать ведущий пробел (" user2@test.ru"). Почтовый сервер отклонит такое письмо с ошибкой SMTP. Обязательно используем функцию СокрЛП() для каждого адреса.
  4. Разные разделители в одной строке:
    Если в строке могут встречаться как запятые, так и точки с запятой, перед разделением рекомендуется привести строку к единому разделителю: СтрокаАдресов = СтрЗаменить(Контрагент.АдресЭлектроннойПочты, ";", ",");

Итоговый пример: формирование и отправка почтового сообщения

Объединим все шаги в единый законченный фрагмент кода для отправки письма нескольким получателям из строки контрагента:


// 1. Создаем объект почтового сообщения
Сообщение = Новый ИнтернетПочтовоеСообщение;
Сообщение.Тема = "Уведомление";
Сообщение.Отправитель = "robot@mycompany.ru";
Сообщение.ИмяОтправителя = "Информационная система";

ТекстПисьма = Сообщение.Тексты.Добавить("Добрый день! Во вложении необходимые документы.");
ТекстПисьма.ТипТекста = ТипТекстаПочтовогоСообщения.ПростойТекст;

// 2. Подготавливаем строку и разделяем на адреса
СтрокаАдресов = СтрЗаменить(Контрагент.АдресЭлектроннойПочты, ";", ",");
МассивАдресов = СтрРазделить(СтрокаАдресов, ",", Ложь);

// 3. Заполняем коллекцию получателей
Для Каждого Адрес Из МассивАдресов Цикл
    ЧистыйАдрес = СокрЛП(Адрес);
    Если Не ПустаяСтрока(ЧистыйАдрес) Тогда
        Сообщение.Получатели.Добавить(ЧистыйАдрес);
    КонецЕсли;
КонецЦикла;

// 4. Проверяем, что есть хотя бы один получатель, и отправляем
Если Сообщение.Получатели.Количество() > 0 Тогда
    Почта = Новый ИнтернетПочта;
    Попытка
        Почта.Подключиться(ПолучитьПрофиль());
        Почта.Послать(Сообщение);
        Почта.Отключиться();
        Сообщить("Письмо успешно отправлено!");
    Исключение
        Почта.Отключиться();
        Сообщить("Ошибка при отправке почты: " + ОписаниеОшибки());
    КонецПопытки;
Иначе
    Сообщить("У контрагента не указаны корректные адреса электронной почты.");
КонецЕсли;

Такой подход обеспечивает корректную обработку списков адресов произвольной длины, предотвращает синтаксические сбои при отправке почты и является стандартом надежного кода в 1С:Предприятии.

← На главную