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