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