При разработке сложных аналитических отчетов в системе компоновки данных (СКД) часто возникает ситуация, когда для каждого уровня иерархии или группировки требуется своя математическая логика расчета ресурса. Например, на нижнем уровне группировки показатель рассчитывается как простое частное, на среднем уровне применяется взвешенная формула, а на верхнем уровне требуется просуммировать полученные промежуточные результаты.
Если для ресурса на вкладке Ресурсы задать раздельные формулы для каждой группировки, а в строке детальных записей оставить 0, то при попытке получить общий итог через стандартное выражение Сумма(ВычисляемоеПоле) в итоговой строке отчета отображается 0.
Разберем причины такого поведения платформы 1С и подробно рассмотрим рабочие способы вычисления общего итога.
Проанализируем логику работы СКД. В отличие от электронных таблиц, система компоновки данных не выполняет суммирование «снизу вверх» (от дочерних строк к родительским). Для каждой строки группировки и для строки «Общий итог» расчет формулы ресурса выполняется независимо по всему набору исходных детальных записей, входящих в текущий разрез.
Если на вкладке Вычисляемые поля для поля задано константное значение 0, а формулы распределены только по группировкам, то при вычислении общего итога выражение Сумма(ВычисляемоеПоле) суммирует нули исходных строк набора данных. Чтобы получить корректный результат, необходимо явно указать СКД алгоритм сбора и агрегации значений с уровня верхней группировки.
Основной и наиболее универсальный способ решения задачи — использование встроенной функции языка выражений СКД ВычислитьВыражениеСГруппировкойМассив. Эта функция формирует массив вычисленных значений для указанного поля группировки, после чего к этому массиву применяется агрегатная функция (например, Сумма).
Разберем по шагам правильную настройку схемы компоновки данных:
Общий итог).Посмотрим на синтаксис выражения для общего итога:
Сумма(ВычислитьВыражениеСГруппировкойМассив("ФормулаВерхнейГруппировки", "ИмяПоляГруппировки1"))
Важно обратить внимание на нюансы синтаксиса:
"Максимум(ПланСтоимостьТК) * Сумма(Приход) / Максимум(ПланТиражКГ)".Сумма(ФормулаРесурса) без строкового контекста функции СКД, система выдаст ошибку «Использование вложенных агрегатных функций не допускается».Посмотрим на практический пример настройки ресурса для общего итога:
Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(СуммаОборот) / Выбор Когда Сумма(КоличествоОборот) = 0 Тогда 1 Иначе Сумма(КоличествоОборот) Конец", "Подразделение"))
Если математическая логика расчета итоговой строки содержит сложные ветвления, проверки или не укладывается в рамки одной строки языка выражений СКД, расчет можно вынести в экспортную функцию серверного общего модуля.
Разберем реализацию этого подхода:
Функция РассчитатьОбщийИтог(МассивЗначений) Экспорт
Результат = 0;
Для Каждого ЗначениеЭлемента Из МассивЗначений Цикл
Если ЗначениеЭлемента <> Неопределено Тогда
Результат = Результат + ЗначениеЭлемента;
КонецЕсли;
КонецЦикла;
Возврат Результат;
КонецФункции
МойОбщийМодульСервер.РассчитатьОбщийИтог(ВычислитьВыражениеСГруппировкойМассив("ФормулаВерхнейГруппировки", "Группировка1"))
Еще один надежный способ избежать сложных конструкций с массивами выражений — пересмотреть структуру вычисляемых полей:
ПолеГруппировка1, ПолеГруппировка2, ПолеИтог.Сумма(...).Такой подход делает схему компоновки данных прозрачной для сопровождения и исключает ошибки вычисления итоговых строк.