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