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