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