Как рассчитать общий итог по вычисляемому полю с разными формулами в группировках СКД?

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

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

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

Разберем причины такого поведения платформы 1С и подробно рассмотрим рабочие способы вычисления общего итога.

Почему в общем итоге получается ноль: механизм агрегации СКД

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

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

Решение 1: Агрегация значений через функцию ВычислитьВыражениеСГруппировкойМассив

Основной и наиболее универсальный способ решения задачи — использование встроенной функции языка выражений СКД ВычислитьВыражениеСГруппировкойМассив. Эта функция формирует массив вычисленных значений для указанного поля группировки, после чего к этому массиву применяется агрегатная функция (например, Сумма).

Разберем по шагам правильную настройку схемы компоновки данных:

  1. Перейдем на вкладку Ресурсы.
  2. Добавим строку для нашего вычисляемого ресурса, оставив колонку Рассчитывать по... пустой (или выбрав значение Общий итог).
  3. В поле Выражение зададим конструкцию агрегации массива.

Посмотрим на синтаксис выражения для общего итога:


Сумма(ВычислитьВыражениеСГруппировкойМассив("ФормулаВерхнейГруппировки", "ИмяПоляГруппировки1"))

Важно обратить внимание на нюансы синтаксиса:

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

Посмотрим на практический пример настройки ресурса для общего итога:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(СуммаОборот) / Выбор Когда Сумма(КоличествоОборот) = 0 Тогда 1 Иначе Сумма(КоличествоОборот) Конец", "Подразделение"))

Решение 2: Передача массива промежуточных данных в функцию общего модуля

Если математическая логика расчета итоговой строки содержит сложные ветвления, проверки или не укладывается в рамки одной строки языка выражений СКД, расчет можно вынести в экспортную функцию серверного общего модуля.

Разберем реализацию этого подхода:

  1. В общем модуле с признаком Сервер создадим экспортную функцию, принимающую массив промежуточных значений:

Функция РассчитатьОбщийИтог(МассивЗначений) Экспорт
    
    Результат = 0;
    Для Каждого ЗначениеЭлемента Из МассивЗначений Цикл
        Если ЗначениеЭлемента <> Неопределено Тогда
            Результат = Результат + ЗначениеЭлемента;
        КонецЕсли;
    КонецЦикла;
    
    Возврат Результат;

КонецФункции
  1. На вкладке Ресурсы СКД для строки общего итога вызываем эту функцию:

МойОбщийМодульСервер.РассчитатьОбщийИтог(ВычислитьВыражениеСГруппировкойМассив("ФормулаВерхнейГруппировки", "Группировка1"))

Решение 3: Разделение показателей на отдельные вычисляемые поля

Еще один надежный способ избежать сложных конструкций с массивами выражений — пересмотреть структуру вычисляемых полей:

  1. На вкладке Вычисляемые поля создадим отдельные поля для каждого уровня иерархии: ПолеГруппировка1, ПолеГруппировка2, ПолеИтог.
  2. Для каждого поля пропишем соответствующее математическое выражение расчета.
  3. На вкладке Ресурсы привяжем каждое созданное поле строго к своей группировке через колонку Рассчитывать по..., используя для них стандартную функцию Сумма(...).

Такой подход делает схему компоновки данных прозрачной для сопровождения и исключает ошибки вычисления итоговых строк.

← На главную