Как в СКД реализовать разный расчет ресурса для разных уровней группировок и корректно распределить показатели

Программист 1С v8.3 (Управляемые формы) Управленческий учет
← На главную

При разработке сложных отчетов в системе компоновки данных (СКД) часто возникает задача распределения одного показателя пропорционально другому. Типичный пример: выручка фиксируется в целом по категории продукции, а нам необходимо увидеть её в разрезе складов, на которых эта продукция была выпущена. Сложность заключается в том, что при простом расчете пропорции на уровне складов, общие итоги по категории могут «поплыть», так как СКД попытается применить ту же формулу распределения к итоговым строкам. Разберем подробно, как настроить систему так, чтобы на уровне склада работала формула распределения, а на уровне категории и общих итогов — простое суммирование.

Проблема распределения и агрегации в СКД

Рассмотрим ситуацию, с которой столкнулся автор темы. Есть данные по выпуску продукции, которые детализированы до склада. И есть данные по выручке, которые известны только для категории продукции в целом. Задача — получить «Выручку по складу». Логическая формула кажется простой: Сумма(ВыпускПоСкладу) / Сумма(ВыпускПоКатегории) * Сумма(ВыручкаПоКатегории).

Однако, если прописать эту формулу в вычисляемом поле или просто в ресурсе для всех уровней, СКД на уровне группировки КатегорияПродукции выполнит расчет заново. Вместо того чтобы сложить распределенные значения по складам, система возьмет общий выпуск по категории, разделит его на общий выпуск (получив 1) и умножит на выручку. На первый взгляд это верно, но при изменении состава группировок или наличии сложных иерархий итоги начинают расходиться с ожиданиями пользователя. Проанализируем, как управлять этим процессом.

Способ 1: Использование вкладки Ресурсы для разделения логики

Самый правильный и надежный метод в 1С — это использование возможности назначать разные выражения для разных уровней группировок непосредственно на вкладке Ресурсы. Выясним, как это сделать пошагово.

  1. Откроем схему компоновки данных и перейдем на закладку Ресурсы.
  2. Добавим наше поле (например, ВыручкаФакт) в список ресурсов первый раз. В колонке Выражение напишем нашу формулу распределения:
    
    Сумма(Выпуск) / ВычислитьВыражение("Сумма(Выпуск)", "КатегорияПродукции") * Сумма(Выручка)
    
  3. В колонке Рассчитывать по... выберем только ту группировку, где нам нужно это распределение — в данном случае это Склад.
  4. Добавим это же поле ВыручкаФакт в список ресурсов второй раз. Но теперь в колонке Выражение укажем простую агрегатную функцию: Сумма(ВыручкаФакт).
  5. В колонке Рассчитывать по... для этой строки выберем вышестоящие уровни: КатегорияПродукции, ВидПродукции и Общий итог.

Важный момент: если мы укажем простую сумму для верхних уровней, СКД будет суммировать значения, полученные из детальных записей или нижестоящих группировок, в зависимости от контекста. Это позволяет «зафиксировать» расчет распределения только на нижнем уровне.

Способ 2: Функция ВычислитьВыражениеСГруппировкойМассив

Проанализируем более продвинутый метод, который часто спасает в ситуациях, когда пользователь может произвольно менять настройки группировок. Если мы хотим, чтобы итог всегда был суммой рассчитанных по складам значений, независимо от того, какие поля выбраны в настройках отчета, следует использовать функцию ВычислитьВыражениеСГруппировкойМассив.

Эта функция позволяет вычислить выражение для каждой строки указанной группировки, поместить результаты в массив, а затем применить к этому массиву другую агрегатную функцию (например, Сумма). Посмотрим на пример выражения для ресурса:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(Выпуск) / ВычислитьВыражение(""Сумма(Выпуск)"", ""КатегорияПродукции"") * Сумма(Выручка)", "Склад"))

В чем преимущество такого подхода? Разберем логику: на любом уровне выше склада СКД сначала «спустится» на уровень склада, выполнит там расчет пропорции для каждого склада отдельно, соберет эти цифры в массив и просто сложит их. Это гарантирует математическую точность итогов.

Защита от деления на ноль и пустых значений

При распределении показателей мы неизбежно сталкиваемся с риском возникновения математических ошибок. Если по какой-то категории продукции не было выпуска (знаменатель равен нулю), отчет может выдать ошибку или пустые значения. Выясним, как сделать формулу устойчивой.

Рекомендуется использовать конструкцию ВЫБОР КОГДА прямо внутри выражения ресурса. Рассмотрим пример:


ВЫБОР 
    КОГДА ВычислитьВыражение("Сумма(Выпуск)", "КатегорияПродукции") = 0 
    ТОГДА 0 
    ИНАЧЕ Сумма(Выпуск) / ВычислитьВыражение("Сумма(Выпуск)", "КатегорияПродукции") * Сумма(Выручка) 
КОНЕЦ

Также полезно использовать функцию ЕСТЬNULL для полей Выпуск и Выручка, если в базе данных могут отсутствовать соответствующие записи. Это предотвратит появление пустых ячеек в отчете, заменяя их нулями, что важно для корректной работы агрегатных функций.

Различие между вычисляемыми полями и ресурсами

Важно понимать фундаментальное различие, которое часто путает начинающих разработчиков 1С. Поля, описанные на вкладке Вычисляемые поля, рассчитываются для каждой детальной записи (строки выборки из базы данных). Если ваша выручка хранится в агрегированном виде (например, по категориям), а склады — это детализация, то на уровне детальных записей пропорция может не иметь смысла, так как там еще нет итогов по категориям.

Помним правило: если расчет требует итогов по группировкам (использования функций Сумма, Максимум и т.д.), его необходимо описывать на вкладке Ресурсы. Вычисляемые поля подходят только для строковых манипуляций или простых арифметических действий внутри одной строки БД (например, Цена * Количество).

Гибкость настроек для пользователя

Если клиент хочет менять состав группировок, использование жестких имен полей в функции ВычислитьВыражение (например, "КатегорияПродукции") может привести к ошибкам, если эта группировка будет удалена из настроек. Чтобы этого избежать, можно использовать параметр "Группировка" или пустые кавычки для расчета в контексте всей иерархии, но это требует осторожности.

Однако наиболее универсальным способом остается настройка ресурсов «Рассчитывать по...». Даже если пользователь уберет группировку Склад из отчета, СКД просто проигнорирует ресурс, настроенный только для этого поля, и будет использовать общее суммовое выражение, что сохранит работоспособность отчета.

Таким образом, мы рассмотрели основные механизмы управления расчетами в СКД. Комбинируя настройки «Рассчитывать по» и мощные функции вычисления выражений по массиву группировок, можно реализовать практически любую бизнес-логику распределения показателей с сохранением идеальной точности итогов.

← На главную