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

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

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

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

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

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

Во-первых, нам необходимо составить запрос к справочнику. Важным моментом здесь является использование ключевого слова ИЕРАРХИЯ в блоке упорядочивания. Проанализируем пример кода:


Запрос = Новый Запрос;
Запрос.Текст = 
"ВЫБРАТЬ
|    Номенклатура.Ссылка КАК Товар
|ИЗ
|    Справочник.Номенклатура КАК Номенклатура
|УПОРЯДОЧИТЬ ПО
|    Ссылка ИЕРАРХИЯ
|АВТОУПОРЯДОЧИВАНИЕ";

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


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

// Передаем полученное дерево в реквизит формы
ЗначениеВРеквизитФормы(Дерево, "ИмяРеквизитаДеревоНаФорме");

Обратите внимание на использование функции ЗначениеВРеквизитФормы. На управляемых формах ДеревоЗначений как объект существует только на сервере. Чтобы данные отобразились в интерфейсе, их нужно поместить в соответствующий реквизит формы, имеющий тип «Дерево значений».

Способ 2. Вывод через Систему компоновки данных (СКД)

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

Проанализируем алгоритм вывода через СКД:

  1. Создаем схему компоновки данных и описываем в ней запрос к справочнику.
  2. Настраиваем группировку в настройках СКД. Для получения иерархии следует использовать тип группировки «Иерархия».
  3. В программном коде используем ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений.

Пример программной реализации:


КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки);

ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(МакетКомпоновки);

ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВКоллекциюЗначений;
ДеревоРезультат = Новый ДеревоЗначений;
ПроцессорВывода.УстановитьОбъект(ДеревоРезультат);

// Метод Вывести() заполнит дерево с учетом настроенной иерархии
ПроцессорВывода.Вывести(ПроцессорКомпоновки);

Этот метод считается более «тяжеловесным», но он незаменим, если структура дерева должна динамически меняться в зависимости от настроек пользователя.

Важные нюансы и ограничения

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

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

2. Пустые группы. Если в запросе используется условие ГДЕ, ограничивающее выборку элементов, то группы, в которых нет подходящих под фильтр элементов, могут просто исчезнуть из результата. В итоге структура «родитель-потомок» может нарушиться. Чтобы сохранить иерархию даже при фильтрации, часто используют метод «снизу вверх», когда сначала выбираются нужные элементы, а затем программно догружаются все их вышестоящие родители.

3. Типизация колонок. При использовании ЗначениеВРеквизитФормы крайне важно, чтобы состав и типы колонок в программно созданном объекте ДеревоЗначений полностью совпадали с составом колонок реквизита на форме. Если в коде вы добавите колонку Цена, а на форме её не будет, данные по этой колонке не отобразятся. Для генерации недостающих полей интерфейса в коде можно использовать пример динамического добавления и удаления элементов формы.

Способ 3. Ручное построение дерева (Рекурсия)

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

Рассмотрим логику построения:


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

Хотя рекурсия дает максимальный контроль над процессом (например, можно программно менять картинки узлов или цвет текста прямо при обходе), она является самой медленной из-за большого количества обращений к базе данных в цикле. Мы советуем использовать её только для небольших объемов данных.

Подведем итог: для быстрого вывода справочника «лесенкой» лучше всего подходит Способ 1 с использованием УПОРЯДОЧИТЬ ПО Ссылка ИЕРАРХИЯ. Это стандарт платформы 1С, обеспечивающий оптимальное сочетание скорости разработки и производительности системы.

← На главную