Как получить реквизиты контрагента на управляемой форме в 1С:Предприятие 8.3?

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

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

Выясним причину: почему обращение через точку не работает на клиенте

В архитектуре управляемого приложения 1С действует строгое разделение логики на клиентскую и серверную части. На тонком и веб-клиенте тип СправочникСсылка представляет собой лишь компактный идентификатор (содержит только ссылку и представление для отображения в интерфейсе). Сами данные объекта в память клиентского приложения не загружаются.

Платформа намеренно блокирует разыменование ссылок (обращение через точку к реквизитам объекта) на клиенте. Если бы такое поведение было разрешено, каждое обращение вызывало бы неявный сетевой синхронный вызов сервера базы данных, что привело бы к серьезным зависаниям интерфейса пользователя. Следовательно, для получения любых дополнительных реквизитов необходимо обращаться к серверу.

Способ 1. Получение реквизита с помощью функции &НаСервереБезКонтекста

Рассмотрим классический и наиболее производительный подход. Для получения данных мы создаем неконтекстную серверную функцию. Использование директивы &НаСервереБезКонтекста гарантирует, что на сервер не передается контекст всей формы (ее элементы и реквизиты), что экономит сетевой трафик и оперативную память.

Разберем по шагам реализацию процедуры:

  1. На клиенте получаем ссылку из реквизита формы Объект.Контрагент.
  2. Передаем ссылку параметром в серверную функцию. Для оптимизации используем ключевое слово Знач.
  3. На сервере получаем нужное значение и возвращаем его на клиент.

Посмотрим на пример кода в модуле формы:


&НаКлиенте
Процедура ПроверитьИННКонтрагента(Команда)
    Если ЗначениеЗаполнено(Объект.Контрагент) Тогда
        ИНН = ПолучитьИННКонтрагентаНаСервере(Объект.Контрагент);
        Сообщить("ИНН контрагента: " + ИНН);
    Иначе
        Сообщить("Контрагент не выбран!");
    КонецЕсли;
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьИННКонтрагентаНаСервере(Знач СсылкаНаКонтрагента)
    // На сервере разыменование ссылки через точку разрешено
    Возврат СсылкаНаКонтрагента.ИНН;
КонецФункции

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

В типовых конфигурациях (таких как «1С:Бухгалтерия предприятия 3.0», «1С:ERP», «1С:Управление торговлей») широко используется Библиотека Стандартных Подсистем. В ней предусмотрен оптимизированный функционал для быстрого чтения данных объектов без создания лишних серверных процедур в самой форме.

Важный нюанс контекста общего модуля: общий модуль ОбщегоНазначения компилируется только на сервере. Если вызвать ОбщегоНазначения.ЗначениеРеквизитаОбъекта(...) прямо в процедуре с директивой &НаКлиенте, возникнет ошибка «Переменная не определена (ОбщегоНазначения)».

Для прямого вызова из клиентского кода в БСП существует специальный модуль с признаком клиентского вызова — ОбщегоНазначенияВызовСервера. Рассмотрим примеры его использования:


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

Метод ЗначенияРеквизитовОбъекта выполняет единый легковесный запрос к базе данных и возвращает структуру с запрошенными полями, что значительно быстрее поштучного обращения.

Способ 3. Отображение реквизита на форме без написания программного кода

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

  1. Откроем форму документа в конфигураторе.
  2. В окне элементов добавим новое Поле надписи или Поле ввода (со свойством ТолькоПросмотр = Истина).
  3. В палитре свойств созданного элемента найдем строку ПутьКДанным (DataPath).
  4. Раскрываем реквизит Объект -> Контрагент -> выбираем ИНН (итоговый путь: Объект.Контрагент.ИНН).

Платформа самостоятельно позаботится об оптимизированном отображении и обновлении значения при смене контрагента пользователем.

Как получить адреса и банковские счета контрагента в 1С:Бухгалтерии 3.0?

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

  1. Контактная информация (адрес, телефон, email): хранится в табличной части КонтактнаяИнформация контрагента. Для ее получения на сервере используют методы модуля УправлениеКонтактнойИнформацией или запросы:
    
    &НаСервереБезКонтекста
    Функция ПолучитьЮридическийАдрес(Знач КонтрагентСсылка)
        // Использование программного интерфейса БСП
        Возврат УправлениеКонтактнойИнформацией.КонтактнаяИнформацияОбъекта(
            КонтрагентСсылка, 
            Справочники.ВидыКонтактнойИнформации.ЮрАдресКонтрагента
        );
    КонецФункции
    
  2. Банковские счета: хранятся в подчиненном справочнике БанковскиеСчета. Ссылка на основной счет контрагента находится в реквизите ОсновнойБанковскийСчет. Получить его реквизиты на сервере можно через запрос либо через БСП:
    
    &НаСервереБезКонтекста
    Функция ПолучитьДанныеБанковскогоСчета(Знач КонтрагентСсылка)
        СтруктураДанных = ОбщегоНазначения.ЗначенияРеквизитовОбъекта(
            КонтрагентСсылка, 
            "ОсновнойБанковскийСчет.НомерСчета, ОсновнойБанковскийСчет.Банк.Наименование, ОсновнойБанковскийСчет.Банк.БИК"
        );
        Возврат СтруктураДанных;
    КонецФункции
    

Типичные ошибки при работе с контекстом формы

Разберем распространенную ошибку: попытку использовать метод формы РеквизитФормыВЗначение для чтения одиночных полей ссылки:


// НЕПРАВИЛЬНО: приведет к ошибке времени выполнения
&НаСервере
Функция ОшибочныйМетод()
    Возврат РеквизитФормыВЗначение("Объект.Контрагент").ИНН; 
КонецФункции

Метод РеквизитФормыВЗначение предназначен исключительно для преобразования основного реквизита формы целиком в объектную модель (например, из реквизита Объект типа ДанныеФормыСтруктура в полноценный ДокументОбъект для проведения или записи). Применение этого тяжелого метода для простого чтения полей ссылок нерационально и перегружает сервер.

← На главную