При работе с Системой Компоновки Данных (СКД) разработчики часто сталкиваются с неочевидным поведением системы при расчете итогов. Типичная задача заключается в том, чтобы получить сумму не по всем детальным записям нижнего уровня, а именно по уже посчитанным итогам вложенной группировки. В данной статье мы разберем, почему СКД ведет себя именно так и как правильно настроить ресурсы, чтобы получить корректный результат.
Основная сложность заключается в том, что по умолчанию СКД при расчете агрегатной функции Сумма() обращается ко всей выборке данных, доступной в контексте текущей группировки. Если вы строите отчет с иерархией (например, Номенклатура -> Заказ), то при попытке вычислить сумму на уровне Номенклатура, система просто «видит» все детальные записи, которые входят в эту номенклатуру, и суммирует их. Если в детальных записях содержатся данные, которые уже были агрегированы на уровне Заказ, вы получаете «задвоение» или «затроение» итогов, так как система игнорирует промежуточный результат и считает всё заново по исходной таблице.
Чтобы заставить СКД учитывать уже вычисленные промежуточные итоги, нам потребуется функция ВычислитьВыражениеСГруппировкойМассив. Она позволяет собрать значения из определенной группировки в массив и уже над этим массивом произвести арифметические операции. Рассмотрим, как это реализовать на практике.
Для настройки ресурсов в СКД выполним следующие шаги:
СКД.ВЗаказеКоличество.Для расчета суммы по группировке Номенклатура на основе итогов вложенной группировки Ссылка (или Документ), воспользуемся следующим выражением:
Сумма(ВычислитьВыражениеСГруппировкойМассив("ПВЗаказеКоличество", "Ссылка"))
Здесь мы явно указываем, что сначала нужно получить массив значений ресурса ПВЗаказеКоличество, сгруппированных по Ссылка, а затем просуммировать эти полученные значения.
Важно понимать, как именно настроить поле Рассчитывать по. Мы рекомендуем использовать двухуровневый подход для того, чтобы СКД четко понимала контекст вычислений:
ВычислитьВыражениеСГруппировкойМассив. Это позволяет «поднять» итоги с нижнего уровня и сложить их между собой, а не суммировать исходные детальные записи.ВЗаказеКоличество, либо используем обычную Сумма(ВЗаказеКоличество), если на этом уровне есть детализация.Если задача требует более гибкого подхода, например, если данные приходят из разных наборов данных, стоит рассмотреть следующие варианты:
Если вам нужно получить значение только одного конкретного поля, можно воспользоваться функцией ВычислитьВыражение. Рассмотрим пример:
ВычислитьВыражение("Сумма(пиКОбеспечению)", , "ГруппировкаНижняя")
Этот метод полезен, если структура отчета не позволяет использовать массив или если нужно обратиться к итогу конкретной именованной группировки. Обратите внимание: использование именованных группировок требует строгого соответствия имени в настройках и в коде выражения.
Часто разработчики задаются вопросом: можно ли подтягивать итоги из другого запроса? Да, это возможно, если вы объединяете данные в СКД через Объединение. В этом случае СКД видит таблицу как единое целое. Если вы связываете наборы данных, убедитесь, что поле, по которому идет связь, присутствует во всех наборах — это позволит корректно «схлопывать» итоги на разных уровнях группировки.
При настройке итогов в СКД придерживайтесь следующих правил:
СКД — это декларативный инструмент, и «принудительная» логика через ВычислитьВыражение — стандартный способ управления контекстом.ВычислитьВыражениеСГруппировкойМассив, убедитесь, что поле группировки указано правильно (в кавычках, как строковое имя поля).Следуя этим рекомендациям, вы сможете добиться корректного отображения итоговых сумм в любых, даже самых сложных отчетах 1С.