При построении отчетов в системе компоновки данных (СКД) нередко возникает необходимость создать нестандартное дерево подчинения элементов, которое не совпадает со штатной иерархией справочника. Однако при попытке установить отбор разработчики сталкиваются с тем, что стандартная фильтрация либо отсекает родительские узлы, либо вовсе ломает структуру дерева. Выясним причину такого поведения и разберем по шагам, как правильно настроить отбор в произвольной иерархии, чтобы выводить всю ветку целиком, если хотя бы один из ее элементов соответствует заданному критерию.
Проанализируем ситуацию: в типовом механизме СКД условия отбора накладываются на записи набора данных еще на этапе выборки. Если условию удовлетворяет дочерний элемент (лист дерева), но не удовлетворяет родительский узел, родитель исключается из итогового результата. В результате цепочка подчинения разрывается, и дочерняя запись либо «теряется», либо выводится в корень отчета без контекста подчинения.
Кроме того, операторы сравнения В группе, В группе из списка и В иерархии по умолчанию рассчитаны на предопределенную иерархию метаданных. При произвольной иерархии платформа не знает, какое поле считать вышестоящим родителем при фильтрации, пока разработчик явно не укажет механизм проверки связей.
Рассмотрим основной способ решения задачи, заложенный разработчиками платформы «1С:Предприятие». Для того чтобы платформа понимала произвольную иерархическую структуру при отборах, используется связка дополнительного набора данных и параметра проверки.
НаборДанныхПроверкаИерархии). В нем описывается связь родительских и дочерних узлов с фильтрацией по специальному параметру:
ВЫБРАТЬ
ИерархияДанных.Ссылка КАК Ссылка,
ИерархияДанных.Родитель КАК Родитель
ИЗ
РегистрСведений.ПользовательскаяИерархия КАК ИерархияДанных
ГДЕ
ИерархияДанных.Родитель В (&РодительПроверки)
НаборДанныхПроверкаИерархии.Ссылка.Родитель.РодительПроверки.НаборДанныхПроверкаИерархии.Важный момент: псевдонимы полей и типы данных в основном наборе и в наборе проверки иерархии должны полностью совпадать. Если типы или имена колонок будут отличаться, сопоставление узлов не произойдет, и в итоговой группировке строки окажутся пустыми.
Разберем еще один вариант, когда требуется вывести родительские уровни ветки до подходящего элемента. Платформа предоставляет возможность регулировать область применения фильтра.
Если отбор задается не в корневых настройках отчета, а в свойствах конкретной строки группировки (на вкладке «Отбор» выбранной группировки), в колонках настройки отбора появляется поле Применение. Оно имеет три режима:
Посмотрим на ситуацию, когда признак соответствия условию может располагаться на любом уровне дерева (как у предка, так и у потомка), и требуется оставить всю вертикальную ветвь. Для этого можно использовать агрегацию через вычисляемые поля.
ПризнакПодходит со значением 1, если условие выполняется, и 0 в противном случае:
ВЫБОР КОГДА Реквизит = &НужноеЗначение ТОГДА 1 ИНАЧЕ 0 КОНЕЦ
Максимум(ПризнакПодходит).ВычислитьВыражение с областью расчета "Иерархия", чтобы «поднять» или «опустить» факт наличия совпадения по всей цепочке подчинения, и наложим отбор на итоговое агрегированное значение.Проанализируем технические ограничения, о которых необходимо помнить при реализации:
Запрос, так как СКД довыбирает данные порциями через передачу параметров в условие ГДЕ. Если данные загружаются из внешней таблицы значений (набор данных Объект), древовидную связность и отбор веток необходимо подготавливать программно в коде до передачи в компоновщик.