При разработке отчетов на Системе компоновки данных (СКД) часто возникает классическая задача: необходимо рассчитать показатель, который является производным от других (например, Цена = Стоимость / Количество или Рентабельность = Прибыль / Выручка). Проблема заключается в том, что если просто добавить такое поле в ресурсы с функцией Сумма(), система начнет складывать уже рассчитанные частные в итогах, что математически неверно. Более того, часто требуется скрыть расчет в детальных записях (строках документов) и оставить его только в итогах по группам.
В этой статье мы подробно разберем несколько способов решения этой задачи, проанализируем работу встроенных функций агрегации и выясним, как избежать ошибок при расшифровке отчета с помощью продвинутой консоли запросов и отчетов — для этого подойдёт продвинутая консоль запросов и СКД для разработчика.
Рассмотрим ситуацию. У нас есть две строки в детальных записях, которые удобно анализировать в консоли запросов:
Если в ресурсах СКД указано Сумма(Цена), то в группировке мы получим 60 (10 + 50). Однако реальная средневзвешенная цена по группе должна быть: (100 + 50) / (10 + 1) = 13.63. Следовательно, выражение для ресурса всегда должно оперировать суммами первичных показателей.
Это один из самых эффективных методов. Мы не создаем сложное выражение на вкладке «Вычисляемые поля», а прописываем логику расчета непосредственно на вкладке «Ресурсы». Рассмотрим по шагам:
Цена. В колонке «Выражение» можно оставить пустое место или поставить 0 (для генерации сложных выражений можно использовать ИИ-помощника для 1С (поможет ИИ-помощник для написания кода и выражений 1С)).Цена в список ресурсов.
Вычислить("Сумма(Стоимость) / Сумма(Количество)", "Группировка")
Разберем параметры функции Вычислить:
Сумма()."Группировка" (в кавычках), расчет будет производиться в контексте текущей строки группировки. Если оставить пустые кавычки "", система будет использовать текущий контекст, что часто помогает избежать проблем при выводе итогов.Более мощный инструмент — функция ВычислитьВыражение, работу которой удобно тестировать через консоль запросов для управляемых форм. Она позволяет гибко управлять контекстом расчета и часто используется, когда нужно избежать ошибок при расшифровке (drill-down).
Пример выражения для ресурса:
ВычислитьВыражение("Сумма(Стоимость) / Выбор Когда Сумма(Количество) = 0 Тогда 1 Иначе Сумма(Количество) Конец", , "Группировка")
Проанализируем этот подход. Здесь мы сразу обрабатываем ситуацию деления на ноль, которая часто возникает в отчетах. Использование пустого второго параметра означает, что вычисление идет по текущему набору данных. Третий параметр "Группировка" указывает системе, что результат должен агрегироваться именно на уровне строк группировки.
Если ваша цель — не просто правильно рассчитать значение, но и скрыть его в детальных записях (в самых нижних строках отчета), воспользуйтесь штатной настройкой СКД:
Цена.Подразделение, Номенклатура и Общий итог).В этом случае в строках с документами или регистраторами поле Цена останется пустым, а в итогах по подразделениям появится корректно рассчитанное значение.
Иногда требуется оставить расчет в ресурсах «как есть», но визуально скрыть значения для определенных условий. Для этого воспользуемся Условным оформлением на вкладке «Настройки»:
СистемныеПоля.УровеньВГруппировке Равно 0 (или другое условие, определяющее детальную запись).Цена.Этот метод хорош тем, что он не влияет на математику расчета, а лишь управляет отображением данных для пользователя.
Частая проблема: при использовании жесткого имени группировки в функции Вычислить (например, "Подразделение"), отчет работает прекрасно, но при попытке расшифровать сумму (двойной клик по ячейке), 1С выдает ошибку, так как в новом окне контекст группировки «Подразделение» может отсутствовать.
Чтобы этого избежать, рекомендуем в выражении ресурса использовать пустую строку в качестве имени группировки:
Вычислить("Сумма(Стоимость) / Сумма(Количество)", "")
В этом случае СКД будет динамически определять текущую группировку, и расшифровка будет работать корректно.
В современных версиях платформы появилось расширенное управление агрегатными функциями. Если вы определили Цена в вычисляемых полях как Стоимость / Количество, то в ресурсах можно использовать:
Агрегат(Цена)
Система СКД достаточно умна, чтобы понять: на уровне группировок нужно не складывать значения Цена, а выполнить деление сумм компонентов, из которых эта цена состоит. Это избавляет от необходимости писать сложные вложенные конструкции Сумма(...) / Сумма(...).
Для реализации корректного расчета «только по группировкам» мы рекомендуем придерживаться следующего алгоритма:
Сумма(А) / Сумма(Б)), а не сумму частных.ВЫБОР КОГДА, чтобы отчет не падал при отсутствии оборотов.Вычислить или ВычислитьВыражение отдавайте предпочтение пустому контексту группировки для сохранения работоспособности расшифровки.