Как вывести итоги по группировкам в динамическом списке 1С

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

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

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

Почему динамический список не рассчитывает итоги по группировкам

Для понимания проблемы разберем механизм работы объекта ДинамическийСписок:

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

Способ 1. Использование агрегирующего подзапроса в произвольном запросе

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

Рассмотрим пример произвольного запроса для динамического списка:


ВЫБРАТЬ
    Т.Измерение1 КАК Измерение1,
    Т.Измерение2 КАК Измерение2,
    Т.Ресурс КАК Ресурс,
    Итоги.СуммаРесурса КАК СуммаПоГруппе
ИЗ
    РегистрСведений.ТестовыйРегистр КАК Т
    ЛЕВОЕ СОЕДИНЕНИЕ (
        ВЫБРАТЬ
            Измерение1 КАК Измерение1,
            СУММА(Ресурс) КАК СуммаРесурса
        ИЗ
            РегистрСведений.ТестовыйРегистр
        СГРУППИРОВАТЬ ПО
            Измерение1
    ) КАК Итоги
    ПО Т.Измерение1 = Итоги.Измерение1

Разберем особенности данного подхода:

  1. Колонка СуммаПоГруппе будет содержать итоговую сумму группы в каждой детальной строке. При настройке группировки по Измерение1 значение также отобразится в соответствующей колонке строки-группировки.
  2. Внимание к производительности: При большом объеме записей в регистре подзапрос с группировкой по всей таблице без внешних фильтров может вызывать замедление при обновлении формы и прокрутке списка.

Способ 2. Замена динамического списка на дерево значений

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

Разберем реализацию по шагам:

  1. Создадим на форме реквизит с типом ДеревоЗначений и выведем его в элементы формы как таблицу.
  2. На сервере выполним запрос с секцией ИТОГИ:

&НаСервере
Процедура ЗаполнитьДеревоНаСервере()
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	ТестовыйРегистр.Измерение1 КАК Измерение1,
        |	ТестовыйРегистр.Измерение2 КАК Измерение2,
        |	ТестовыйРегистр.Ресурс КАК Ресурс
        |ИЗ
        |	РегистрСведений.ТестовыйРегистр КАК ТестовыйРегистр
        |ИТОГИ
        |	СУММА(Ресурс)
        |ПО
        |	Измерение1";
        
    РезультатЗапроса = Запрос.Выполнить();
    
    // Выгружаем результат запроса в дерево с сохранением иерархии и итогов
    Дерево = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкамСИерархией);
    
    ЗначениеВРеквизитФормы(Дерево, "ДеревоДанных");
    
КонецПроцедуры

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

Способ 3. Использование отчета на СКД

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

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

Способ 4. Расчет в событии ПриПолученииДанныхНаСервере

В случаях, когда требуется динамический список без тяжелых соединений в запросе, можно задействовать обработчик события ПриПолученииДанныхНаСервере у динамического списка.

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

← На главную