Как получить значение из справочника в вычисляемом поле СКД?

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

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

Почему стандартная конструкция ЗНАЧЕНИЕ() не работает в вычисляемых полях?

Для начала проанализируем ситуацию. В языке запросов 1С конструкция ЗНАЧЕНИЕ() работает безупречно, позволяя получать ссылки на предопределенные элементы. Однако вычисляемые поля СКД используют не язык запросов, а собственный язык выражений СКД.

В языке выражений СКД функция ЗНАЧЕНИЕ() действительно возвращает объектную ссылку. Но вычислитель выражений имеет ограничение: он не всегда может корректно «разыменовать» (получить доступ к полям) ссылку, полученную таким способом прямо в строке выражения. Когда мы пишем ЗНАЧЕНИЕ(Справочник.ПредопределенныеЭлементы.Товар).Значение, парсер СКД ожидает, что перед точкой будет либо поле из набора данных, либо функция. Ссылка, возвращаемая встроенной конструкцией, в данном контексте часто воспринимается как атомарный объект, свойства которого недоступны для прямого обращения.

Способ 1. Использование параметров с выражениями (наиболее оптимальный)

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

Разберем по шагам, как это настроить:

  1. Перейдем на закладку Параметры в схеме компоновки данных.
  2. Добавим новый параметр, например, с именем ТоварЗначение.
  3. Установим для него подходящий тип данных.
  4. В колонке Выражение пропишем путь к значению: ПредопределенныеЗначения.Справочник.ПредопределенныеЭлементы.Товар.Значение
  5. Снимем галочку Включать в доступные поля, чтобы пользователь не видел этот технический параметр в настройках.

Теперь в вычисляемом поле нам достаточно просто обратиться к этому параметру: &ТоварЗначение. Вычисление произойдет однократно при инициализации компоновки, что значительно быстрее, чем обращение к базе данных в каждой строке.

Способ 2. Вызов функций общих модулей

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

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

В выражении вычисляемого поля напишем:


ОбщегоНазначения.ЗначениеРеквизитаОбъекта(ЗНАЧЕНИЕ(Справочник.ПредопределенныеЭлементы.Товар), "Значение")

Важный нюанс производительности: Этот метод следует использовать с осторожностью. Если ваш отчет содержит десятки тысяч строк, вызов функции общего модуля для каждой строки приведет к выполнению отдельного запроса к базе данных (проблема N+1). Это может существенно замедлить формирование отчета. Используйте этот подход только для небольших выборок или итоговых записей.

Способ 3. Модификация основного запроса (Левое соединение)

Если данные нужны массово и быстро, наиболее правильным архитектурным решением будет получение этого значения непосредственно в запросе набора данных. Мы можем присоединить справочник настроек к основной выборке.

Рассмотрим пример запроса:


ВЫБРАТЬ
    Продажи.Номенклатура,
    Продажи.Количество,
    Настройки.Значение КАК ТехническийПараметр
ИЗ
    РегистрНакопления.Продажи КАК Продажи
        ЛЕВОЕ СОЕДИНЕНИЕ Справочник.ПредопределенныеЭлементы КАК Настройки
        ПО Настройки.Имя = "Товар"

В данном случае мы один раз выполняем соединение на уровне СУБД. Это гарантирует максимальную скорость работы. Поле ТехническийПараметр станет доступно в СКД автоматически, и его можно будет использовать в любых вычислениях без дополнительных хитростей.

Способ 4. Работа с типами через ВЫРАЗИТЬ

Выясним еще одну причину, почему в вычисляемом поле может быть «пустота». Если поле Значение в вашем справочнике имеет составной тип данных, СКД может испытывать трудности с автоматическим определением типа при выводе.

В таких ситуациях рекомендуется явно приводить тип в выражении вычисляемого поля:


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

Это подскажет системе, как именно нужно интерпретировать и отображать полученную ссылку.

Резюме и рекомендации

Подводя итог, проанализируем, какой метод выбрать в зависимости от ситуации:

Помните, что использование ЗНАЧЕНИЕ() в языке выражений СКД имеет свои границы, и знание альтернативных механизмов компоновки данных позволяет создавать более стабильные и производительные отчеты.

← На главную