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