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