При работе с Системой компоновки данных (СКД) в 1С:Предприятии часто возникает необходимость вычислять сложные итоговые значения, такие как средневзвешенные. Это требует особого подхода к формулам ресурсов, особенно при использовании функций агрегации, таких как ВычислитьВыражение. В этом руководстве мы подробно рассмотрим, как избежать типичных ошибок и правильно настроить расчет средневзвешенных значений в ваших отчетах.
Рассмотрим ситуацию, когда необходимо получить средневзвешенное значение, например, "произведение по колонкам, деленное на себестоимость", итоговое значение которого не сходится из-за некорректного суммирования. Наш первоначальный запрос заключался в вычислении произведения полей "Себестоимость номенклатуры текущая" и "Средние продажи за 12 мес." только по подразделению. При этом поле "Средние продажи за 12 мес." само по себе является рассчитанным ресурсом по формуле: ВычислитьВыражение("СУММА(СебестоимостьНоменклатурыТекущая)")/ВычислитьВыражение("СУММА(СуммаПродажиСреднееГод)").
Первая попытка рассчитать "Произведение" выглядела так:
ВЫРАЗИТЬ(ВычислитьВыражение("СУММА(СебестоимостьНоменклатурыТекущая)","Подразделение")/ВычислитьВыражение("СУММА(СуммаПродажиСреднееГод)", "Подразделение"), "ЧИСЛО(15,2)")*ВЫРАЗИТЬ(ВычислитьВыражение("СУММА(СебестоимостиНоменклатурыТекущая)","Подразделение"), "ЧИСЛО(15,2)")
Такая формула, примененная непосредственно в ресурсе, привела к расхождению итоговых сумм, поскольку агрегатные функции, примененные к уже агрегированным значениям, могут давать неверный результат. Например, вместо ожидаемых 388 114 625,7 получалось 330 330 980,04.
Прежде чем перейти к правильному решению, давайте разберем, как работает функция ВычислитьВыражение в СКД и почему ее некорректное использование может приводить к ошибкам.
ВычислитьВыражение: Эта функция, имеющая синтаксис ВычислитьВыражение(Выражение, Группировка), предназначена для вычисления агрегатного выражения в контексте указанной группировки, а не в контексте текущей строки или текущей группировки отчета.ВычислитьВыражение("СУММА(Поле)", "Подразделение"), мы получаем сумму определенного поля для всего подразделения. Важно понимать, что это значение будет одинаковым для всех детальных записей, относящихся к одному подразделению.СУММА), может произойти "суммирование сумм". Это означает, что одно и то же агрегатное значение по подразделению будет просуммировано несколько раз для каждой детальной строки в этом подразделении, что приводит к завышенным и некорректным итогам. Именно эта ситуация описывается фразой "сумма улетела в космос".Общая математическая формула для средневзвешенного значения выглядит так:
СУММА(Значение * Вес) / СУММА(Вес)
Для корректного расчета таких показателей в СКД необходимо сначала вычислить "числитель" (Значение * Вес) на максимально детальном уровне, где эти поля доступны. Затем мы должны отдельно просуммировать этот числитель и отдельно просуммировать "вес" (знаменатель) для получения итогового средневзвешенного значения.
Давайте разберем по шагам, как правильно настроить расчет вашего "произведения" и последующего средневзвешенного значения.
Наша цель – "сумму произведений по колонкам разделить на себестоимость". Это означает, что "Произведение" является числителем нашего средневзвешенного значения. Предположим, что поля СебестоимостьНоменклатурыТекущая (далее СНТ) и СуммаПродажиСреднееГод (далее СПСГ) доступны в запросе на уровне детальных записей.
Нам необходимо сначала получить "средние продажи за 12 месяцев" (ваш СрПродажи12Мес) на том уровне, где мы хотим его использовать для умножения. Если СрПродажи12Мес должно быть рассчитано для каждого подразделения как СУММА(СНТ) / СУММА(СПСГ) по подразделению, то мы можем сделать это отдельным вычисляемым полем (не ресурсом) в СКД или прямо в формуле следующего шага.
Предположим, мы хотим получить этот коэффициент для всего подразделения. Вычисляемое поле может быть названо КоэффициентПродажПоПодразделению с формулой:
ВычислитьВыражение("СУММА(СебестоимостьНоменклатурыТекущая)","Подразделение") / ВычислитьВыражение("СУММА(СуммаПродажиСреднееГод)", "Подразделение")
Важно: Если вы используете это как отдельное вычисляемое поле, убедитесь, что оно корректно выводится на уровне подразделения. Однако, часто удобнее встраивать его непосредственно в формулу следующего шага.
Теперь создадим вычисляемое поле (не ресурс) в СКД. Назовем его, например, ПроизведениеДетальное. Его формула должна выглядеть следующим образом:
ВЫРАЗИТЬ(ВычислитьВыражение("СУММА(СебестоимостьНоменклатурыТекущая)","Подразделение") / ВычислитьВыражение("СУММА(СуммаПродажиСреднееГод)", "Подразделение"), "ЧИСЛО(15,2)") * СебестоимостьНоменклатурыТекущая
Давайте разберем эту формулу:
ВычислитьВыражение("СУММА(СебестоимостьНоменклатурыТекущая)","Подразделение") / ВычислитьВыражение("СУММА(СуммаПродажиСреднееГод)", "Подразделение"): Эта часть вычисляет наш коэффициент продаж, агрегированный по всему подразделению.ВЫРАЗИТЬ(..., "ЧИСЛО(15,2)"): Приводим результат к нужному типу и точности.* СебестоимостьНоменклатурыТекущая: Ключевой момент! Мы умножаем этот агрегированный по подразделению коэффициент на детальное значение СебестоимостьНоменклатурыТекущая для каждой строки. Это позволяет получить значение произведения для каждой детальной строки, но с использованием коэффициента, рассчитанного для всего подразделения. Таким образом, мы получаем "числитель" нашей будущей средневзвешенной формулы, рассчитанный на максимально детальном уровне, прежде чем его суммировать.Теперь, когда у нас есть ПроизведениеДетальное для каждой строки, мы можем правильно его просуммировать.
Перейдем на вкладку "Ресурсы" и создадим новый ресурс (или переименуем существующий) с названием "Произведение". Установим для него простое выражение:
СУММА(ПроизведениеДетальное)
Теперь СКД будет корректно суммировать значения ПроизведениеДетальное, которые уже содержат внутри себя правильным образом рассчитанный коэффициент по подразделению.
Для этого ресурса "Произведение" на вкладке "Ресурсы" установим свойство "Рассчитывать по..." для необходимых группировок. В нашем случае это будет "Подразделение" и/или "ОбщийИтог". Это позволит СКД правильно просуммировать значения ПроизведениеДетальное только на выбранных уровнях, избегая избыточного суммирования на детальных строках, где это не требуется.
Для нашего средневзвешенного значения нам также понадобится сумма "веса", который в нашем случае является СебестоимостьНоменклатурыТекущая.
Создадим еще один ресурс, например, СуммаСебестоимостиОбщая, с простым выражением:
СУММА(СебестоимостьНоменклатурыТекущая)
Для этого ресурса также укажем "Рассчитывать по..." для тех же группировок, что и для ресурса "Произведение" (например, "Подразделение" и "ОбщийИтог").
Наконец, мы можем вычислить наше итоговое средневзвешенное значение, используя ранее созданные ресурсы.
Создадим новый ресурс СредневзвешенноеЗначение с выражением:
Произведение / СуммаСебестоимостиОбщая
Этот ресурс будет корректно вычислять средневзвешенное значение, используя суммированный "числитель" и суммированный "знаменатель" на необходимых уровнях группировок.
Настройка "Рассчитывать по..." на вкладке "Ресурсы" является критически важной для корректного отображения итогов:
При работе со сложными формулами в СКД всегда рекомендуется разбивать их на более простые вычисляемые поля и ресурсы. Выводите их в отчет по отдельности, чтобы убедиться, что каждый компонент рассчитывается корректно на всех нужных уровнях группировки. Сравнивайте полученные промежуточные значения с ожидаемыми, это поможет быстро найти место ошибки.
Использование этих подходов позволит вам правильно настроить расчет итогов и избежать ошибок, связанных с некорректным агрегированием значений на разных уровнях группировок в СКД, получая точные средневзвешенные значения.