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

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

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

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем типы данных и рассмотрим правильные варианты решения как на сервере, так и с помощью оптимизированных вызовов.

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

Рассмотрим, почему обращение Услуга.Стоимость на клиенте не работает так, как ожидается:

  1. Ограничение работы со ссылочными типами на клиенте. Платформа 1С 8.3 не загружает полные данные объектов базы данных на клиентскую сторону в целях экономии памяти и оптимизации сетевого трафика. На клиенте ссылка содержит лишь базовую информацию (наименование и уникальный идентификатор), а реквизиты справочника через точку недоступны.
  2. Особенности типа строки табличной части. Строка табличной части на форме имеет тип ДанныеФормыЭлементКоллекции. У этого объекта нет метода Свойство(), так как данный метод предназначен исключительно для коллекций типа Структура и Соответствие. Попытка вызвать Элемент.Свойство("Стоимость") вернет Ложь.

Решение: Получение реквизита на сервере

Для корректного считывания реквизитов объекта из базы данных необходимо выполнять обращение в контексте сервера. Обратим внимание на структуру обращения: строка табличной части содержит реквизит Услуга (ссылку на справочник), а уже у этого объекта есть реквизит Стоимость.

Разберем рабочий пример процедуры, которая перебирает табличную часть ДопУслуги объекта формы и считывает цену услуги на сервере:


&НаСервере
Процедура ПереборСтрокТабличнойЧасти()
    Для Каждого Стр Из Объект.ДопУслуги Цикл
        // Проверяем заполненность ссылки перед обращением
        Если ЗначениеЗаполнено(Стр.Услуга) Тогда
            Сообщить(Стр.Услуга.Стоимость);
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

В данном коде Стр — это текущая строка коллекции Объект.ДопУслуги, Стр.Услуга — ссылка на справочник, а Стр.Услуга.Стоимость — обращение к реквизиту справочника на сервере.

Оптимизация: получение данных для текущей строки без полного перебора

Если задача заключается в заполнении стоимости при выборе услуги в событии УслугиУслугаПриИзменении, перебирать всю коллекцию в цикле не требуется. Более эффективный подход — получить текущую строку на клиенте и запросить реквизит выбранной ссылки на сервере без передачи контекста всей формы.

Посмотрим на пример правильной организации кода в форме:


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

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

Использование директивы &НаСервереБезКонтекста существенно повышает производительность, так как с клиента на сервер передается только конкретная ссылка ТекущаяСтрока.Услуга, а не вся форма целиком.

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

В типовых конфигурациях 1С (например, УТ, ERP, БП, УНФ) для получения значений реквизитов ссылочных объектов не нужно создавать отдельные серверные функции. Для этого в БСП предусмотрен готовый метод:


Стоимость = ОбщегоНазначенияВызовСервера.ЗначениеРеквизитаОбъекта(ТекущаяСтрока.Услуга, "Стоимость");

Этот вызов можно выполнять непосредственно с клиента — функция скомпилирована с вызовом сервера, поэтому платформа самостоятельно обратится к базе данных и вернет требуемое значение.

← На главную