Как в отчете СКД посчитать сумму максимумов в общих итогах?

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

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

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

Выясним причину некорректного расчета

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

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

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

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

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

  1. Перейдем на закладку Ресурсы и добавим две строки для одного и того же поля (например, План).
  2. Для первой строки зададим расчет для базовой группировки строки:

    Выражение: Максимум(План)

    В колонке Рассчитывать по укажем имя конкретной группировки (например, Заказчик).

  3. Для второй строки настроим расчет суммы массивов для итоговых строк:

    Выражение: Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(План)", "Заказчик"))

    В колонке Рассчитывать по выберем ОбщийИтог (а также вышестоящие группировки при их наличии).

Если структура отчета сложная и включает вложенную иерархию (например, Организация → Заказчик → Договор), во втором параметре функции необходимо перечислить через запятую все поля, определяющие уникальность строки на рассчитываемом уровне:

Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(План)", "Организация, Заказчик, Договор"))

Способ 2. Разделение на два набора данных и настройка связей

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

  1. НаборДанных_План: запрос, выбирающий исключительно плановые показатели в разрезе аналитики (без соединения с фактическими движениями).
  2. НаборДанных_Факт: запрос, выбирающий фактические движения.
  3. Перейдем на вкладку Связи наборов данных и свяжем НаборДанных_План (источник) с НаборДанных_Факт (приемник) по полям аналитики (например, Заказчик).

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

Способ 3. Предварительная агрегация во временных таблицах

Если отчет строится на одном наборе данных типа «Запрос», проанализируем структуру текста запроса. Наиболее производительный способ устранения дублей — свертка данных до выполнения соединения:

  1. Поместим фактические данные во временную таблицу, выполнив группировку и суммирование до уровня аналитики плана.
  2. Выполним соединение таблицы плановых показателей с уже сгруппированной временной таблицей факта по принципу «один к одному» или через оператор ОБЪЕДИНИТЬ ВСЕ.
  3. Поскольку дублирование строк исключено на уровне СУБД, в схеме компоновки для всех ресурсов указывается стандартное выражение Сумма().

Важные особенности и ограничения

При выборе метода решения обратим внимание на ключевые нюансы:

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