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

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

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

Разбор типичной ошибки: почему прямое обращение не работает?

Рассмотрим ситуацию, когда в модуле формы документа вы пытаетесь написать код типа ПолучательПисьма = Объект.Email.EmailАдрес. Если система выдает ошибку "Поле объекта не обнаружено" или возвращает пустое значение, это происходит по одной из двух причин:

  1. Отсутствие связи в данных: Переменная Объект ссылается на данные текущей формы (документа). Если в самом документе нет реквизита Email (ссылка на справочник), то обратиться к нему через точку невозможно.
  2. Незаполненное поле: Даже если реквизит Email добавлен в документ, но пользователь не выбрал конкретный элемент из справочника на форме, обращение к его свойствам через точку вернет пустое значение.

Выясним причину, по которой нам нужно искать данные напрямую в справочнике. Если логика программы подразумевает, что получатель должен определяться автоматически в зависимости от типа документа (например, "Оплата счета" или "Новая задача"), нам необходимо выполнить программный поиск в справочнике Email по заданному критерию.

Способ №1: Использование метода НайтиПоРеквизиту

Если нам нужно найти один единственный адрес, соответствующий определенному условию, мы можем воспользоваться методом НайтиПоРеквизиту. Однако здесь критически важно учитывать типы данных.

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

Рассмотрим правильный пример кода для поиска адреса:


&НаСервере
Процедура SMTPОтправка()
    // Укажем событие, для которого ищем почту
    НужноеСобытие = Перечисления.СобытияДляОтправки.ОплатаСчета;
    
    // Выполняем поиск элемента в справочнике
    СсылкаНаEmail = Справочники.Email.НайтиПоРеквизиту("Событие", НужноеСобытие);
    
    Если Не СсылкаНаEmail.Пустая() Тогда
        ПолучательПисьма = СсылкаНаEmail.EmailАдрес;
        
        // Далее идет стандартный код формирования письма
        Письмо = Новый ИнтернетПочтовоеСообщение;
        Письмо.Получатели.Добавить(ПолучательПисьма);
        
        // ... (настройка профиля и отправка)
    Иначе
        Сообщить("Адрес для события " + НужноеСобытие + " не найден в справочнике!");
    КонецЕсли;
КонецПроцедуры

Важный момент: для корректной и быстрой работы метода НайтиПоРеквизиту у соответствующего реквизита в конфигураторе должно быть установлено свойство Индексировать.

Способ №2: Использование запроса (рекомендуемый подход)

Метод НайтиПоРеквизиту возвращает только один (первый попавшийся) элемент. Но что делать, если для одного события (например, "Бухгалтерия") в справочнике заведено несколько адресов? В этом случае правильнее и эффективнее использовать механизм запросов.

Разберем по шагам, как получить список адресов с помощью запроса:


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

Использование запроса позволяет нам гибко фильтровать данные, например, исключать элементы, помеченные на удаление (ПометкаУдаления), и получать только нужные поля, не загружая в память весь объект справочника.

Дополнительные рекомендации по настройке отправки

Даже если адрес успешно получен из справочника, отправка может не состояться из-за технических ограничений почтовых серверов. Рассмотрим важные настройки, которые необходимо учесть в коде:

  1. Пароли приложений: Современные сервисы (Yandex, Mail.ru, Gmail) не позволяют использовать основной пароль от почты для авторизации через сторонние программы. Вам необходимо создать в настройках безопасности почтового ящика специальный пароль приложения и вставлять в код именно его.
  2. Использование SSL: При использовании порта 465 обязательно устанавливайте свойство Профиль.ИспользоватьSSLSMTP = Истина.
  3. Библиотека стандартных подсистем (БСП): Если ваша конфигурация построена на базе типового решения (например, "Бухгалтерия предприятия" или "УНФ"), мы рекомендуем использовать встроенную подсистему "Электронная почта". Вместо создания ИнтернетПочтовыйПрофиль вручную, лучше использовать справочник УчетныеЗаписиЭлектроннойПочты, где настройки хранятся в удобном для пользователя интерфейсе.

Посмотрим, как выглядит проверка корректности адреса перед отправкой. Это поможет избежать падения программы при наличии опечаток в справочнике:


Адрес = ВыборкаДетальныеЗаписи.EmailАдрес;
Если СтрНайти(Адрес, "@") > 0 И СтрНайти(Адрес, ".") > 0 Тогда
    Письмо.Получатели.Добавить(Адрес);
КонецЕсли;

Таким образом, мы проанализировали основные способы обращения к реквизитам справочника из модуля формы. Помните, что для разовых задач подходит НайтиПоРеквизиту, но для надежных и масштабируемых систем использование запросов является "золотым стандартом" разработки в среде 1С.

← На главную