Как правильно использовать оператор В ИЕРАРХИИ в вычисляемых полях и выражениях СКД

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

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

Способ 1. Использование подзапроса в выражении ВЫБОР

Один из самых прямолинейных способов, который позволяет избежать жесткой привязки к параметрам на форме, — это использование вложенного запроса прямо в тексте вычисляемого поля или выражения ресурса. Рассмотрим этот пример подробнее. Если нам нужно проверить вхождение в конкретную группу по ее коду, синтаксис будет выглядеть следующим образом:


Выбор 
    Когда Номенклатура В ИЕРАРХИИ (Выбрать Ссылка Из Справочник.Номенклатура Где Код = "00000000004") 
        Тогда Стоимость 
    Иначе 0 
Конец

Проанализируем эту конструкцию. Здесь внутри оператора В ИЕРАРХИИ мы используем конструкцию ВЫБРАТЬ...ИЗ...ГДЕ. Это позволяет динамически получить ссылку на нужную группу по её уникальному коду прямо в момент расчета выражения. Однако помните, что поиск по текстовому коду считается "плохим тоном" в разработке, так как при изменении кода в справочнике отчет перестанет работать. Используйте этот метод осторожно.

Способ 2. Использование параметров СКД

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

Во-первых, в самом выражении (например, в вычисляемом поле) мы пишем условие, ссылаясь на параметр:

Выбор Когда Номенклатура В ИЕРАРХИИ (&РодительНоменклатуры) Тогда Стоимость Иначе 0 Конец

Во-вторых, необходимо правильно настроить сам параметр на закладке "Параметры" в схеме компоновки данных:

  1. Убедитесь, что тип параметра соответствует типу проверяемого поля (например, СправочникСсылка.Номенклатура).
  2. В колонке "Доступные значения" можно ограничить выбор только группами, если это необходимо.
  3. Важный момент: если вы хотите, чтобы проверка работала именно по иерархии, в настройках отбора или при установке значения параметра важно передавать именно Группу, а не отдельный элемент (хотя оператор В ИЕРАРХИИ корректно обработает и элемент, просто поиск по дереву вниз не даст результатов, если у элемента нет подчиненных).

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


ГруппаОбъект = Справочники.Номенклатура.НайтиПоКоду("00000000004");
Запрос.УстановитьПараметр("РодительНоменклатуры", ГруппаОбъект);

Способ 3. Перенос логики в основной запрос набора данных

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

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


ВЫБРАТЬ
    Номенклатура,
    Стоимость,
    ВЫБОР
        КОГДА Номенклатура В ИЕРАРХИИ (&Родитель)
            ТОГДА ИСТИНА
        ИНАЧЕ ЛОЖЬ
    КОНЕЦ КАК ЭтоНужнаяГруппа
ИЗ
    Справочник.Номенклатура

Теперь в настройках СКД мы можем просто обращаться к полю ЭтоНужнаяГруппа. Это работает значительно быстрее, так как СУБД оптимизирует выполнение таких условий на уровне SQL-запроса.

Способ 4. Использование функций общего модуля

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

Создайте в общем модуле (с флагами "Сервер" и "Вызов сервера") функцию:


Функция ПроверитьВхождениеВГруппу(ТекущаяНоменклатура, ЭталоннаяГруппа) Экспорт
    Возврат ТекущаяНоменклатура.ПринадлежитЭлементу(ЭталоннаяГруппа);
КонецФункции

В выражении вычисляемого поля СКД вызовите эту функцию:

ИмяВашегоОбщегоМодуля.ПроверитьВхождениеВГруппу(Номенклатура, &Родитель)

Внимание: данный метод может существенно замедлить формирование отчета на больших объемах данных из-за постоянных обращений из компоновщика к серверному коду.

Важные технические нюансы

Проанализируем основные причины, по которым оператор В ИЕРАРХИИ может не работать:

  1. Разница между "В" и "В ИЕРАРХИИ": Оператор В проверяет только точное совпадение со списком элементов. Оператор В ИЕРАРХИИ включает в проверку всех потомков указанной группы на всех уровнях вложенности.
  2. Типы данных: Проверьте, что в параметре &Родитель не передается пустая ссылка или значение другого типа. Пустая ссылка в параметре В ИЕРАРХИИ может привести к тому, что условие не выполнится ни для одной строки.
  3. Ограничения СКД: В некоторых версиях платформы использование В ИЕРАРХИИ в вычисляемых полях требует, чтобы иерархия была доступна в самом наборе данных. Убедитесь, что у поля Номенклатура правильно настроены связи (Parent/Родитель).

Таким образом, мы разобрали основные способы решения задачи. Оптимальным вариантом для производительности является перенос логики в текст запроса, а самым гибким — использование параметров СКД с типом СправочникСсылка.

← На главную