При разработке отчетов в Системе компоновки данных (СКД) программисты часто сталкиваются с ситуацией, когда значение ресурса должно рассчитываться по сложной логике только на уровне определенной группировки (например, «Водитель» или «Номенклатура»). Однако стандартные механизмы агрегации 1С при расчете «Общего итога» пытаются применить ту же самую формулу ко всему массиву данных, что приводит к неверным результатам. Вместо того чтобы просто сложить уже полученные итоги по группам, система пересчитывает выражение заново.
Рассмотрим детально, как решить проблему «итогов от итогов» и заставить СКД корректно суммировать результаты группировок.
Проанализируем ситуацию на примере автора темы. Имеется вычисляемое поле СуммаДоплаты. Логика его расчета завязана на показателях пробега и суточных. Если мы просто укажем в ресурсах Сумма(СуммаДоплаты), СКД выполнит сложение на уровне детальных записей. Если же мы пропишем сложную формулу в ресурсе, например:
Выбор
Когда Сумма(Пробег) <> 0
Тогда Сумма(Пробег) * (10 - (Сумма(СуммаПробег) + Сумма(СуммаСуточных)) / Сумма(Пробег))
Иначе 0
Конец
То на уровне Общего итога система подставит в эту формулу суммарный пробег по всем водителям и суммарные суточные. Математически «результат от суммы» почти никогда не равен «сумме результатов». Нам же нужно именно сложить готовые значения, полученные по каждому водителю в отдельности.
Это наиболее эффективный и современный метод в 1С 8.3 для решения задач подобного типа. Данная функция позволяет СКД сформировать временную таблицу в памяти, рассчитать в ней данные по нужной нам группировке, а затем применить к этой таблице агрегатную функцию (например, Сумма).
Разберем по шагам, как настроить ресурс для Общего итога:
СуммаДоплаты создадим две строки.Водитель. Здесь мы пишем нашу обычную формулу расчета доплаты. В колонке Рассчитывать по... выбираем только «Водитель».
Сумма(ВычислитьВыражениеСГруппировкойТаблицей("Выбор Когда Пробег <> 0 Тогда Пробег * (10 - (СуммаПробег + СуммаСуточных)/Пробег) Иначе 0 Конец", "Водитель"))
В колонке Рассчитывать по... для этой строки выберем только «Общий итог».
Что здесь происходит: СКД сначала «пробежится» по всем водителям, вычислит для каждого из них доплату по формуле, соберет эти значения в таблицу и в самом конце просто просуммирует их. Это именно тот результат, который мы ожидаем увидеть в подвале отчета.
Иногда полезно вынести часть логики непосредственно в Вычисляемые поля. Посмотрим на этот вариант подробнее. Если мы определим логику расчета на уровне строк, мы можем столкнуться с тем, что деление на пробег будет происходить в каждой строке табеля, что даст ошибку в итоговой средней. Поэтому важно соблюдать иерархию агрегатов.
Проанализируем типичную ошибку: использование функции Вычислить() внутри выражения ресурса. Как заметил автор в сообщении 8, использование ВычислитьВыражение(..., , "ОбщийИтог") может привести к тому, что сумма получается больше или меньше ожидаемой. Это происходит из-за того, что функция без параметров группировки может учитывать детальные записи или дублировать данные при наличии нескольких вложенных группировок.
Чтобы избежать этого, рекомендуется:
NULL с помощью функции ЕстьNULL(), так как пустые значения в ресурсах могут «ломать» арифметику итогов.Выясним причину, по которой у многих разработчиков итоги «пустые» или «нулевые». Часто это связано с тем, что в настройках ресурса в колонке Рассчитывать по... не установлены флажки напротив нужных группировок или общего итога.
Если ваше выражение использует функции ВычислитьВыражение, убедитесь, что:
Предположим, нам нужно рассчитать «Итог по табелю», который является суммой доплат. Рассмотрим, как будет выглядеть итоговая настройка ресурсов:
Для группировки по Водителю:
Вычислить("Сумма(Пробег) * 10", "Группировка")
Для Общего итога:
Сумма(ВычислитьВыражениеСГруппировкойТаблицей("Сумма(Пробег) * 10", "Водитель"))
Такой подход гарантирует, что 1С не будет пытаться умножить весь пробег парка на 10, а корректно сложит результаты каждого водителя. Это критически важно в задачах логистики, расчета заработной платы и управленческого учета, где тарифы и коэффициенты могут меняться от группы к группе.
Если вы обнаружили, что ручная сумма строк меньше, чем общий итог в отчете, проанализируйте следующие моменты:
"Первая" и "Последняя" в рамках текущей группировки.Использование описанных методов позволит вам создавать сложные аналитические отчеты с математически точными итогами, независимо от вложенности группировок и сложности формул расчета ресурсов.