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