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