Как правильно вывести иерархический отчет с группировками на форме 1С?

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

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

Почему Динамический список не подходит для группировок?

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

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

Реализация дерева данных на форме

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

Шаг 1: Создание реквизита формы

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

Шаг 2: Получение данных запросом

Чтобы получить данные в иерархическом виде, воспользуйтесь стандартным механизмом Запроса с использованием ИТОГИ ПО. Пример запроса:


ВЫБРАТЬ
    ОбъемПродажОбороты.Дата КАК Дата,
    ОбъемПродажОбороты.Менеджер КАК Менеджер,
    ОбъемПродажОбороты.Заказ КАК Заказ,
    ОбъемПродажОбороты.СуммаОборот КАК Сумма
ИЗ
    РегистрНакопления.ОбъемПродаж.Обороты(&НачалоПериода, &КонецПериода) КАК ОбъемПродажОбороты
ИТОГИ
    СУММА(Сумма)
ПО
    Дата,
    Менеджер,
    Заказ

Шаг 3: Выгрузка результата в Дерево значений

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


Запрос = Новый Запрос;
// ... установка параметров запроса ...
РезультатЗапроса = Запрос.Выполнить();

// Выгружаем в дерево с иерархией
ДеревоЗначений = РезультатЗапроса.Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам);

// Теперь загружаем полученное дерево в реквизит формы
ЗначениеВРеквизитФормы(ДеревоЗначений, "ДеревоДанных");

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

  1. Ограничение объема данных: Дерево значений загружается в память целиком (на клиенте). Если данных в регистре слишком много, это может привести к зависанию формы. Всегда накладывайте жесткие отборы по периоду или другим аналитикам.
  2. Альтернатива в виде СКД: Если вам нужен интерактивный отчет с возможностью настройки группировок самим пользователем, не изобретайте велосипед — используйте объект Отчет, построенный на Системе Компоновки Данных. Его можно встроить в форму через Табличный документ, что даст вам гибкость без потери производительности.
  3. Программное управление: Помните, что дерево на форме — это не Динамический список. Вы не сможете просто «обновить» его нажатием кнопки, если данные изменились. Вам придется заново выполнять запрос и обновлять Дерево значений.

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

← На главную