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