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

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

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

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

Проанализируем классическую многоуровневую структуру отчета:

Наша цель — рассчитать некоторый показатель (например, максимум или среднее) на уровне «Характеристика», а затем сложить эти полученные значения на уровне «Производитель», полностью проигнорировав промежуточные группы номенклатуры и саму номенклатуру.

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

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

Рассмотрим синтаксис этой функции:

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

Разберем по шагам, как составить формулу для нашего примера:

  1. Выражение: Формула, которую нужно рассчитать для каждой уникальной записи нижней группировки. В нашем случае это "Максимум(Количество)".
  2. ВыраженияПолейГруппировки: Имя поля группировки, по которому собираются данные. Указываем строкой: "Характеристика".

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


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

Шаг 2. Настройка вкладки «Ресурсы» в схеме компоновки данных

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

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

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

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

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


СоединитьСтроки(ВычислитьВыражениеСГруппировкойМассив("Характеристика", "Характеристика", "Максимум(Количество) > 10"), ", ")

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

Важные особенности производительности и ограничения

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

Альтернатива: Оптимизация на уровне запроса

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

Выполним это по следующему алгоритму:

  1. Создадим временную таблицу (ВТ), в которой сгруппируем исходные данные до уровня «Производитель» и «Характеристика», и сразу рассчитаем нужный максимум:
    
    ВЫБРАТЬ
        Продажи.Производитель КАК Производитель,
        Продажи.Характеристика КАК Характеристика,
        МАКСИМУМ(Продажи.Количество) КАК МаксимальноеКоличество
    ПОМЕСТИТЬ ВТ_МаксимумыХарактеристик
    ИЗ
        РегистрНакопления.Продажи КАК Продажи
    ГРУППИРОВАТЬ ПО
        Продажи.Производитель,
        Продажи.Характеристика
    ;
    
  2. В основном запросе обратимся к созданной временной таблице и сгруппируем данные до уровня производителей, получив искомую сумму максимумов:
    
    ВЫБРАТЬ
        ВТ.Производитель КАК Производитель,
        СУММА(ВТ.МаксимальноеКоличество) КАК ИтоговыйПоказатель
    ИЗ
        ВТ_МаксимумыХарактеристик КАК ВТ
    ГРУППИРОВАТЬ ПО
        ВТ.Производитель
    

При таком подходе СУБД (например, MS SQL Server или PostgreSQL) выполнит группировку и агрегацию на своей стороне в разы быстрее, задействовав индексы, а СКД получит уже готовые сжатые данные для вывода в отчет без необходимости производить сложные манипуляции с массивами в оперативной памяти.

← На главную