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