При разработке функционала отправки сообщений из системы 1С начинающие программисты часто сталкиваются с проблемой: как правильно передать в почтовый профиль адрес получателя, если он хранится в справочнике, а не задан жестко в коде. В этой статье мы подробно разберем, как реализовать механизм поиска нужного адреса, проанализируем типичные ошибки и рассмотрим наиболее эффективные способы решения этой задачи с использованием встроенного языка 1С.
Рассмотрим ситуацию, когда в модуле формы документа вы пытаетесь написать код типа ПолучательПисьма = Объект.Email.EmailАдрес. Если система выдает ошибку "Поле объекта не обнаружено" или возвращает пустое значение, это происходит по одной из двух причин:
Объект ссылается на данные текущей формы (документа). Если в самом документе нет реквизита Email (ссылка на справочник), то обратиться к нему через точку невозможно.Email добавлен в документ, но пользователь не выбрал конкретный элемент из справочника на форме, обращение к его свойствам через точку вернет пустое значение.Выясним причину, по которой нам нужно искать данные напрямую в справочнике. Если логика программы подразумевает, что получатель должен определяться автоматически в зависимости от типа документа (например, "Оплата счета" или "Новая задача"), нам необходимо выполнить программный поиск в справочнике Email по заданному критерию.
Если нам нужно найти один единственный адрес, соответствующий определенному условию, мы можем воспользоваться методом НайтиПоРеквизиту. Однако здесь критически важно учитывать типы данных.
Проанализируем ситуацию, когда в справочнике есть реквизит Событие, имеющий тип ПеречислениеСсылка. Одной из главных ошибок новичков является попытка найти элемент по строковому представлению (например, "Оплата счета"). В 1С это не сработает, так как поиск должен идти по ссылке на объект перечисления.
Рассмотрим правильный пример кода для поиска адреса:
&НаСервере
Процедура SMTPОтправка()
// Укажем событие, для которого ищем почту
НужноеСобытие = Перечисления.СобытияДляОтправки.ОплатаСчета;
// Выполняем поиск элемента в справочнике
СсылкаНаEmail = Справочники.Email.НайтиПоРеквизиту("Событие", НужноеСобытие);
Если Не СсылкаНаEmail.Пустая() Тогда
ПолучательПисьма = СсылкаНаEmail.EmailАдрес;
// Далее идет стандартный код формирования письма
Письмо = Новый ИнтернетПочтовоеСообщение;
Письмо.Получатели.Добавить(ПолучательПисьма);
// ... (настройка профиля и отправка)
Иначе
Сообщить("Адрес для события " + НужноеСобытие + " не найден в справочнике!");
КонецЕсли;
КонецПроцедуры
Важный момент: для корректной и быстрой работы метода НайтиПоРеквизиту у соответствующего реквизита в конфигураторе должно быть установлено свойство Индексировать.
Метод НайтиПоРеквизиту возвращает только один (первый попавшийся) элемент. Но что делать, если для одного события (например, "Бухгалтерия") в справочнике заведено несколько адресов? В этом случае правильнее и эффективнее использовать механизм запросов.
Разберем по шагам, как получить список адресов с помощью запроса:
&НаСервере
Процедура ОтправитьПисьмоПоЗапросу()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ
| Email.EmailАдрес КАК EmailАдрес
|ИЗ
| Справочник.Email КАК Email
|ГДЕ
| Email.Событие = &Событие
| И НЕ Email.ПометкаУдаления";
// Устанавливаем параметр запроса - ссылку на перечисление
Запрос.УстановитьПараметр("Событие", Перечисления.СобытияДляОтправки.ОплатаСчета);
РезультатЗапроса = Запрос.Выполнить();
ВыборкаДетальныеЗаписи = РезультатЗапроса.Выбрать();
Письмо = Новый ИнтернетПочтовоеСообщение;
Пока ВыборкаДетальныеЗаписи.Следующий() Цикл
// Добавляем всех найденных получателей в письмо
Если ЗначениеЗаполнено(ВыборкаДетальныеЗаписи.EmailАдрес) Тогда
Письмо.Получатели.Добавить(ВыборкаДетальныеЗаписи.EmailАдрес);
КонецЕсли;
КонецЦикла;
Если Письмо.Получатели.Количество() > 0 Тогда
// Выполняем отправку
// ...
Иначе
Сообщить("Список получателей пуст.");
КонецЕсли;
КонецПроцедуры
Использование запроса позволяет нам гибко фильтровать данные, например, исключать элементы, помеченные на удаление (ПометкаУдаления), и получать только нужные поля, не загружая в память весь объект справочника.
Даже если адрес успешно получен из справочника, отправка может не состояться из-за технических ограничений почтовых серверов. Рассмотрим важные настройки, которые необходимо учесть в коде:
Профиль.ИспользоватьSSLSMTP = Истина.ИнтернетПочтовыйПрофиль вручную, лучше использовать справочник УчетныеЗаписиЭлектроннойПочты, где настройки хранятся в удобном для пользователя интерфейсе.Посмотрим, как выглядит проверка корректности адреса перед отправкой. Это поможет избежать падения программы при наличии опечаток в справочнике:
Адрес = ВыборкаДетальныеЗаписи.EmailАдрес;
Если СтрНайти(Адрес, "@") > 0 И СтрНайти(Адрес, ".") > 0 Тогда
Письмо.Получатели.Добавить(Адрес);
КонецЕсли;
Таким образом, мы проанализировали основные способы обращения к реквизитам справочника из модуля формы. Помните, что для разовых задач подходит НайтиПоРеквизиту, но для надежных и масштабируемых систем использование запросов является "золотым стандартом" разработки в среде 1С.