Как просуммировать итоги вычисляемого поля по группировкам в СКД

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

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

Постановка задачи и анализ проблемы

Представим ситуацию: у нас есть отчет по расходу топлива. На уровне группировки ТранспортноеСредство мы рассчитываем экономию или перерасход по формуле:

(НормаРасхода * ПробегЗаПериод) / 100 - ИзрасходованоЛитров

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

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

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

Рассмотрим по шагам, как настроить такой расчет на закладке Ресурсы:

  1. Перейдем на закладку Ресурсы в схеме компоновки данных.
  2. В поле "Выражение" для нашего ресурса (например, ЭкономияПерерасход) пропишем следующую конструкцию:

Сумма(ВычислитьВыражениеСГруппировкойМассив("Сумма(НормаРасхода * ПробегЗаПериод) / 100 - Сумма(ИзрасходованоЛитров)", "ТранспортноеСредство"))

Разберем, что происходит в этом выражении:

Решение 2: Разделение формул для разных уровней группировок

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

Выполним следующие действия в настройках ресурсов:

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

Таким образом, СКД поймет, что на нижнем уровне (ТС) нужно применить сложную логику, а на верхних уровнях достаточно просто просуммировать уже полученные результаты нижнего уровня.

Обработка пустых значений и NULL

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

Посмотрим на пример безопасной формулы:


Сумма(ЕстьNull(НормаРасхода, 0) * ЕстьNull(ПробегЗаПериод, 0)) / 100 - Сумма(ЕстьNull(ИзрасходованоЛитров, 0))

Это гарантирует, что даже при отсутствии данных по одной из машин, общая сумма по организации будет рассчитана корректно.

Когда использовать ВычислитьВыражениеСГруппировкойТаблицаЗначений?

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

Пример синтаксиса (упрощенно):


Сумма(ВычислитьВыражениеСГруппировкойМассив("МойСложныйРасчет", "ТранспортноеСредство", "Пробег > 1000"))

Здесь мы добавили третий параметр — отбор. Это позволяет суммировать итоги только по тем транспортным средствам, которые соответствуют определенному условию.

Важные рекомендации по производительности

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

Подведем итог: суммирование вычисляемых полей — это стандартная задача, которая решается либо через специализированные функции работы с группировками в ресурсах, либо через явное указание разных формул для разных уровней иерархии в настройках СКД.

← На главную