Как избавиться от задвоения записей и настроить расчет итогов при выводе иерархии в СКД?

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

При построении отчетов в системе компоновки данных (СКД) с использованием стандартной группировки типа «Иерархия» разработчики часто сталкиваются с ситуацией, когда элемент справочника выводится дважды: сначала в качестве узла группировки со свернутыми суммами, а затем отдельной строкой детальной записи со своим собственным количеством. Попытка настроить отбор по функции Уровень() нередко приводит к ошибке «Выражение не может быть вычислено "Level"». Разберем по шагам, почему возникает эта проблема и как правильно настроить схему компоновки данных.

Причины задвоения записей и ошибки вычисления уровня

Проанализируем механику работы СКД при формировании иерархических отчетов:

  1. Стандартное поведение иерархии: Когда в структуре отчета выбирается тип группировки «Иерархия», платформа автоматически разворачивает дерево родителей. Если в выборке присутствуют числовые показатели как по родительским узлам, так и по подчиненным, СКД генерирует заголовок иерархического уровня и детальные строки внутри него, дублируя родительский элемент.
  2. Область действия функции Уровень(): Системные функции Уровень() и системное поле УровеньВГруппировке определены только в контексте группировочных записей. Если отбор или вычисляемое поле применяется к детальным записям или задается на корневом уровне отчета без указания области применения, СКД выдает ошибку невозможности расчета уровня.
  3. Потеря листовых элементов: При попытке исключить родительские дубли простой проверкой на неравенство вышестоящему элементу отсекаются элементы, не имеющие подчиненных записей (листовые узлы).

Способ 1. Исключение дублей через пользовательские поля и настройку применения отбора

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

  1. Перейдем на вкладку «Настройки» в схеме компоновки данных и откроем вкладку «Пользовательские поля».
  2. Добавим «Новое поле-выражение» (например, с именем РодительскийУзел) и укажем формулу:
    
    Выбор
        Когда Уровень() = 0
            Тогда Неопределено
        Иначе ВычислитьВыражение("Ссылка", , "ИЕРАРХИЯ")
    Конец
    
  3. Перейдем к настройке конкретной иерархической группировки в дереве структуры отчета.
  4. На вкладке «Отбор» группировки добавим условие: Ссылка Не равно ПользовательскиеПоля.РодительскийУзел
  5. Важный шаг: Чтобы избежать ошибки Выражение не может быть вычислено "Level", в свойствах созданного элемента отбора переключим параметр «Применение» в значение «После группировки или для иерархии» (или «Для иерархии»).
  6. Чтобы не потерять одиночные элементы без подчинения, объединим условия в группу «ИЛИ», добавив проверку верхнего уровня через СистемныеПоля.УровеньВГруппировке Равно 1.

Способ 2. Раздельный расчет сумм для иерархических узлов и детальных записей

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

  1. Откроем вкладку «Ресурсы» в схеме компоновки данных.
  2. Для базового расчета детальных записей укажем стандартную агрегатную функцию: Сумма(Количество)
  3. Добавим в таблицу ресурсов еще одну строку для того же поля Количество. В колонке «Рассчитывать по...» выберем значение ИмяГруппировки Иерархия.
  4. В колонке «Выражение» пропишем алгоритм расчета именно для иерархических строк. Если значение берется из подчиненных узлов или вычисляется по особому правилу, используем агрегатные функции СКД для массивов: ВычислитьВыражениеСГруппировкойМассив("Сумма(Количество)", "ИмяГруппировки") или условие через Выбор Когда ... Тогда ... Конец, что позволит гибко переопределить выводимые показатели для папок и конечных элементов.

Способ 3. Построение собственной иерархии через связи наборов данных

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

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