Как в СКД рассчитать итоги по иерархии элементов и корректно вывести дерево?

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

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

При стандартной настройке отчета разработчики сталкиваются с рядом трудностей: задвоение строк при иерархическом выводе, некорректный расчет ресурсов и принудительное отображение всей вышестоящей цепочки предков от самого корня. Разберем по шагам, как правильно настроить ресурсы СКД и структуру отчета для решения этой задачи.

Расчет итогов по подчиненным элементам через функции СКД

Проанализируем задачу расчета ресурсов. Нам необходимо получить две колонки:

  1. Собственные продажи: сумма продаж непосредственно текущего контрагента.
  2. Сумма продаж подчиненных + свои: агрегированная сумма текущего узла и всех нижележащих узлов его ветки.

Для собственного показателя на вкладке Ресурсы используется стандартное выражение:

Сумма(СуммаПродаж)

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

ВычислитьВыражение("Сумма(СуммаПродаж)", "Контрагент", "ГруппировкаНеРесурса")

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


Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(СуммаПродаж)", "Контрагент", "Иерархия"))

Данные выражения заставляют СКД агрегировать показатели по всему дереву подчинения, корректно суммируя собственные данные родительского элемента со всеми его потомками на любой глубине.

Устранение дублирования строк при иерархии элементов

Выясним причину дублирования записей. В справочниках с иерархией «Группы и элементы» папки не содержат собственных движений в регистрах. Но в иерархии «Элементы» каждый элемент одновременно выступает и узлом иерархии, и носителем собственных данных. Из-за этого СКД по умолчанию может выводить строку узла-родителя, а под ней — ту же самую строку в качестве детальной записи.

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

  1. Настройка типа группировки: В настройках структуры отчета для группировки Контрагент вместо стандартного типа «Иерархия» укажем тип «Только иерархия». В этом случае компоновщик не создает дублирующую детальную строку под узлом, а объединяет вывод в одну строку.
  2. Фильтрация через системные поля: Если требуется дополнительное разделение, на группировку можно наложить отбор, исключающий повторные записи с помощью вычисляемых выражений контекста иерархии.

Отсечение вышестоящих узлов при отборе по ветке дерева

Разберем ситуацию, когда пользователь устанавливает отбор по конкретному родителю (например, показать структуру только под выбранным контрагентом). По умолчанию СКД достраивает всю цепочку предков от самого корня справочника, выводя вышестоящие элементы с нулевыми значениями.

Для того чтобы отчет начинался строго с выбранного узла и не отображал пустые родительские уровни, применим один из следующих подходов:

  1. Построение иерархии через связи наборов данных:

    На вкладке Связи наборов данных настраиваем рекурсивную связь набора с самим собой:

    — Источник связи: НаборДанных1

    — Приемник связи: НаборДанных1

    — Выражение источник: Родитель (или реквизит связи)

    — Выражение приемник: Ссылка

    — Иерархия: флаг включен

    — Начальное значение связи: параметр отбора &ВыбранныйКонтрагент

    При таком подходе СКД строит дерево сверху вниз строго от указанного элемента, не обращаясь к вышестоящим узлам.

  2. Настройка отбора группировки «После группировки или для иерархии»:

    Если используется стандартная группировка по иерархии, в свойствах элемента отбора группировки необходимо переключить режим применения условия на «После группировки или для иерархии». Это позволит отсечь строки предков, не удовлетворяющие условиям отбора.

Оптимизация производительности на больших справочниках

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

Для высоконагруженных систем целесообразно использовать паттерн Closure Table (таблица связей):

  1. Создаем непериодический независимый регистр сведений (например, ИерархияКонтрагентов) с измерениями РодительУзла и ПодчиненныйУзел.
  2. При записи элемента справочника программно заполняем регистр всеми связями «предок — потомок» на всю глубину.
  3. В запросе СКД соединяем продажи с регистром по условию ИерархияКонтрагентов.РодительУзла = &ВыбранныйКонтрагент. Это позволяет получить все данные по подчиненным элементам одним простым и быстрым запросом без использования тяжелых иерархических конструкций платформы.
← На главную