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

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

Анализ проблемы и причин ошибки

Рассмотрим распространенную ситуацию в управляемом приложении 1С: при изменении номенклатуры в табличной части документа требуется получить её реквизиты (например, базовую единицу измерения, ставку НДС или артикул).

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

Ошибки при передаче контекста на сервер

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

Выясним правильный подход: на сервер необходимо передавать только саму ссылку на номенклатуру (СтрокаТЧ.Номенклатура).

Способ 1. Вызов внеконтекстной серверной функции

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

На клиенте мы получаем ссылку из текущей строки табличной части и передаем её в функцию. На сервере считываем реквизит напрямую через точку от ссылки:


&НаКлиенте
Процедура ТоварыНоменклатураПриИзменении(Элемент)
    
    СтрокаТЧ = Элементы.Товары.ТекущиеДанные;
    Если СтрокаТЧ = Неопределено Тогда
        Возврат;
    КонецЕсли;
    
    // Передаем на сервер только ссылку
    СтрокаТЧ.ЕдиницаИзмерения = ПолучитьЕдиницуИзмеренияНаСервере(СтрокаТЧ.Номенклатура);
    
КонецПроцедуры

&НаСервереБезКонтекста
Функция ПолучитьЕдиницуИзмеренияНаСервере(СсылкаНоменклатура)
    
    Если Не ЗначениеЗаполнено(СсылкаНоменклатура) Тогда
        Возврат Неопределено;
    КонецЕсли;
    
    // Обращаемся к реквизиту напрямую через точку от ссылки
    Возврат СсылкаНоменклатура.ЕдиницаИзмерения;
    
КонецФункции

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

Способ 2. Использование функций БСП

Проанализируем работу в типовых конфигурациях на базе Библиотеки Стандартных Подсистем (БСП). Для быстрого получения данных без написания собственных серверных функций используются вызовы общего модуля:


// Получение одного реквизита
ЕдИзм = ОбщегоНазначенияВызовСервера.ЗначениеРеквизитаОбъекта(СтрокаТЧ.Номенклатура, "ЕдиницаИзмерения");

// Получение нескольких реквизитов за один вызов
СтруктураРеквизитов = ОбщегоНазначенияВызовСервера.ЗначенияРеквизитовОбъекта(
    СтрокаТЧ.Номенклатура, 
    "ЕдиницаИзмерения, СтавкаНДС, Артикул"
);

СтрокаТЧ.ЕдиницаИзмерения = СтруктураРеквизитов.ЕдиницаИзмерения;
СтрокаТЧ.СтавкаНДС        = СтруктураРеквизитов.СтавкаНДС;

Способ 3. Использование составного пути к данным в форме

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

  1. Откроем конструктор формы документа.
  2. Добавим колонку в таблицу формы и укажем путь к данным через точку: Товары.Номенклатура.ЕдиницаИзмерения.
  3. Платформа 1С автоматически подтянет и закэширует значение данного реквизита при выборе номенклатуры без написания программного кода.

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

← На главную