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

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

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

Причина проблемы: Контекст выполнения и ссылочные типы

Проанализируем ситуацию: когда вы находитесь в модуле формы, вы работаете с данными, которые «проброшены» на форму. Реквизит Объект.Email в документе хранит только ссылку (уникальный идентификатор записи в базе данных), а не все данные справочника сразу. Рассмотрим, почему обращение напрямую не работает:

  1. На клиенте (&НаКлиенте): Реквизиты справочника по ссылке недоступны. Вы видите только саму ссылку (имя или код), но база данных не позволяет «прыгнуть» внутрь объекта без обращения к серверу.
  2. На сервере (&НаСервере): Технически обращение через точку вида Объект.Email.EmailАдрес возможно, но оно имеет свои подводные камни. Если реквизит Email не заполнен, попытка обратиться к его свойству вызовет ошибку. Кроме того, такое обращение заставляет систему считывать весь объект справочника из базы ради одного поля, что избыточно и замедляет работу системы.

Решение 1: Обращение через точку на сервере (простой способ)

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


&НаСервере
Процедура SMTPОтправка()
    
    // Проверим, заполнена ли ссылка на справочник в документе
    Если Не ЗначениеЗаполнено(Объект.Email) Тогда
        Сообщить("Не выбран получатель в поле Email!");
        Возврат;
    КонецЕсли;

    // Получаем адрес напрямую (работает только на сервере)
    // Важно: проверьте правильность написания имени реквизита в конфигураторе!
    ПолучательПисьма = Объект.Email.EmailАдрес; 

    Профиль = Новый ИнтернетПочтовыйПрофиль;
    Профиль.АдресСервераSMTP = "smtp.yandex.ru";
    Профиль.ПортSMTP = 465;
    Профиль.ИспользоватьSSLSMTP = Истина;
    // ... остальные настройки профиля ...

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

КонецПроцедуры

Решение 2: Использование запроса (профессиональный подход)

Выясним причину, по которой опытные разработчики предпочитают запросы. Запрос позволяет извлечь из базы данных только одно конкретное поле, не загружая в память весь объект справочника. Это значительно экономит ресурсы сервера, особенно если справочник «тяжелый» (содержит много реквизитов или табличных частей).

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


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

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

Если ваша конфигурация создана на базе современных решений (например, 1С:Бухгалтерия 3.0 или 1С:УТ 11), в ней наверняка есть встроенные механизмы для быстрого получения данных. Проанализируем использование модуля ОбщегоНазначения. Это самый короткий и эффективный способ получения реквизита по ссылке.

Посмотрим на пример кода:


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

Типичные ошибки при обращении к данным

Рассмотрим ситуации, когда код все равно выдает ошибку, даже если вы написали его на сервере:

Рекомендации по безопасности при отправке почты

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

Что нужно сделать:

  1. В настройках почты (Яндекс, Mail.ru, Google) включите доступ по протоколу SMTP.
  2. Создайте специальный «Пароль приложения». Обычный пароль для входа в почту через браузер работать не будет — серверы отклонят соединение из соображений безопасности.
  3. Используйте правильные порты: для SSL это обычно порт 465.

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

← На главную