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

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

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

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

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

Представим ситуацию, когда данные в наборе записей выглядят следующим образом:

  1. Заказ 1 — РТУ 1 — Количество: 2
  2. Заказ 1 — РТУ 2 — Количество: 3
  3. Заказ 2 — РТУ 1 — Количество: 4
  4. Заказ 2 — РТУ 2 — Количество: 5
  5. Заказ 3 — РТУ 3 — Количество: 9

Если мы хотим сгруппировать данные по «РТУ» и получить сумму максимумов, расчет должен быть следующим:

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

Решение с помощью функции ВычислитьВыражениеСГруппировкойМассив

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

Разберем синтаксис формулы, которую необходимо прописать в поле «Выражение» на закладке «Ресурсы»:


Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(Количество)", "ДокументРТУ"))

Рассмотрим подробнее, как работает эта конструкция:

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

Реализация при использовании собственных макетов

Часто программисты сталкиваются с тем, что сложные формулы ресурсов перестают работать, если в отчете используется не автоматическая генерация макета, а собственный макет, созданный на закладке «Макеты». Выясним причину этого поведения.

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

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

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


Сумма(ВычислитьВыражениеСГруппировкойМассив("Максимум(ЕстьNull(Количество, 0))", "ДокументРТУ"))

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

Альтернативный метод: Агрегация на уровне запроса

Иногда задачу можно решить еще до передачи данных в СКД — непосредственно в тексте запроса. Этот метод полезен, если объем данных очень велик, и формирование огромных массивов в памяти СКД замедляет отчет. Рассмотрим пример такого запроса:


ВЫБРАТЬ
    ВложенныйЗапрос.СсылкаРТУ,
    МАКСИМУМ(ВложенныйЗапрос.Количество) КАК МаксКолВо
ПОМЕСТИТЬ ВТ_Максимумы
ИЗ
    (ВЫБРАТЬ
        Т.ДокументРТУ КАК СсылкаРТУ,
        Т.Количество КАК Количество
    ИЗ
        ДанныеДокументов КАК Т) КАК ВложенныйЗапрос
ГРУППИРОВАТЬ ПО
    ВложенныйЗапрос.СсылкаРТУ
;

////////////////////////////////////////////////////////////////////////////////
ВЫБРАТЬ
    СУММА(ВТ_Максимумы.МаксКолВо) КАК ИтоговоеКоличество
ИЗ
    ВТ_Максимумы КАК ВТ_Максимумы

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

Производительность и ограничения

Важно помнить, что функция ВычислитьВыражениеСГруппировкойМассив выполняет вычисления в оперативной памяти на стороне сервера 1С. Посмотрим, к чему это может привести на больших объемах:

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

Резюме

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

  1. Для решения задачи используйте ресурс с формулой Сумма(ВычислитьВыражениеСГруппировкойМассив(...)).
  2. Указывайте вторым параметром функции ту группировку, по которой нужно найти максимум.
  3. Всегда обрабатывайте возможные значения NULL через ЕстьNULL.
  4. При использовании собственных макетов проверяйте соответствие имен ресурсов и уровней их расчета.

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

← На главную