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

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

При разработке интерфейсов в 1С часто возникает задача отобразить данные не в виде плоского списка, а в виде иерархии. Классический пример — группировка продаж по менеджерам, где внутри каждого менеджера отображаются его контрагенты. В этой статье мы разберем, почему стандартная ТабличнаяЧасть объекта не подходит для этих целей напрямую и какими инструментами можно добиться желаемого результата, включая программное изменение форм или использование вспомогательных инструментов, таких как редактор форм в режиме предприятия — для этого есть инструмент Flowcon для сборки интерфейсов и динамических списков.

Проблема использования стандартной табличной части

Проанализируем ситуацию: стандартный объект платформы ТабличнаяЧасть (документа или справочника) всегда является «плоским». В базе данных такие данные хранятся строками, и платформа не предусматривает визуального «схлопывания» строк в узлы внутри самой табличной части. Если мы попытаемся вывести данные запросом с итогами напрямую в таблицу, мы получим дублирование данных в колонках, как это показано в обсуждении на форуме.

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

Способ 1. Использование Дерева значений на форме

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

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

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

Шаг 2. Размещение на форме

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

Шаг 3. Заполнение дерева данными из запроса

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


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

Использование метода Выгрузить(ОбходРезультатаЗапроса.ПоГруппировкам) — это ключевой момент. Он автоматически создает подчиненные строки для каждой группировки, указанной в секции ПО вашего запроса.

Способ 2. Синхронизация с табличной частью объекта

Часто иерархия нужна лишь для удобства ввода, а хранить данные нужно в обычной ТабличнойЧасти документа. Разберем, как обеспечить связь между ними. Мы можем скрыть реальную табличную часть с формы и показывать пользователю только ДеревоЗначений.

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

Выгрузка данных: перед записью объекта нам нужно выполнить обратную операцию — «развернуть» дерево обратно в плоский список. Проанализируем пример функции обхода дерева:


&НаСервере
Процедура ПередЗаписьюНаСервере(Отказ, ТекущийОбъект, ПараметрыЗаписи)
    
    // Очищаем реальную табличную часть объекта
    ТекущийОбъект.СоставПродаж.Очистить();
    
    // Получаем дерево из реквизита формы
    ДеревоОбъект = РеквизитФормыВЗначение("ДеревоДанныхНаФорме");
    
    // Рекурсивно или циклами обходим дерево
    Для Каждого СтрокаМенеджер Из ДеревоОбъект.Строки Цикл
        Для Каждого СтрокаКонтрагент Из СтрокаМенеджер.Строки Цикл
            НоваяСтрока = ТекущийОбъект.СоставПродаж.Добавить();
            НоваяСтрока.Менеджер = СтрокаМенеджер.Менеджер;
            НоваяСтрока.Контрагент = СтрокаКонтрагент.Контрагент;
            НоваяСтрока.Сумма = СтрокаКонтрагент.Сумма;
        КонецЦикла;
    КонецЦикла;
    
КонецПроцедуры

Способ 3. Динамический список с группировками

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

Разберем, как настроить иерархию в ДинамическомСписке без сложного программирования:

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

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

Важные нюансы и советы

Рассмотрим несколько практических моментов, которые помогут сделать работу со списками более профессиональной:

Подведем итог: выбор инструмента зависит от бизнес-задачи. Нужно редактирование и хранение в документе — выбираем ДеревоЗначений с ручной синхронизацией. Нужно быстрое и красивое отображение данных из базы — используем ДинамическийСписок с настроенными группировками.

← На главную