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