При разработке интерфейсов на управляемых формах часто возникает задача отобразить список элементов справочника в виде дерева, аналогично тому, как это сделано в типовых формах списка. Однако при попытке простого копирования реквизита или настройки произвольного запроса разработчики часто сталкиваются с тем, что данные отображаются «плоским» списком. В этой статье мы подробно разберем, как заставить Динамический список работать в режиме дерева, особенно если речь идет о подчиненных справочниках.
Прежде всего, проанализируем, как 1С:Предприятие строит иерархию в динамическом списке. Для этого платформе необходимо четко понимать структуру данных: какое поле является ссылкой, какое — родителем, а какое — владельцем (для подчиненных справочников). Если вы используете Произвольный запрос без указания Основной таблицы, платформа обрабатывает его как обычную выборку из базы данных, не применяя механизмы автоматического построения дерева.
Рассмотрим по шагам, как правильно настроить реквизит формы типа ДинамическийСписок для работы с иерархией.
Это критически важный этап. Если в свойствах динамического списка не указана Основная таблица, свойство иерархического просмотра работать не будет. Платформа должна «знать», метаданные какого объекта используются, чтобы подтянуть связи Родитель — Ссылка.
Выполним следующие действия в конфигураторе:
Список (или вашего динамического списка).Справочник.Номенклатура или Справочник.СкладскиеЯчейки).Важный нюанс: при редактировании запроса рекомендуется сначала выбрать основную таблицу, а уже затем включать флаг Произвольный запрос. Это позволит платформе автоматически сопоставить поля.
После настройки реквизита необходимо правильно сконфигурировать визуальный элемент на форме. Проанализируем свойства таблицы формы, отображающей наш список:
Дерево.Если справочник имеет иерархию групп и элементов, этих настроек достаточно для корректного отображения дерева.
Ситуация усложняется, когда мы работаем с подчиненными справочниками (например, «Складские ячейки», подчиненные «Складам»). Выясним причину, по которой стандартное дерево может «разваливаться» в этом случае. Для подчиненных объектов платформа ожидает, что в списке будет установлен отбор по конкретному Владельцу. Если отбор не установлен, дерево может отображаться некорректно или превращаться в плоский список.
Если нам нужно видеть общее дерево по всем владельцам, рассмотрим вариант с использованием Группировок в настройках динамического списка:
КомпоновщикНастроек).Владелец, а внутрь него добавим группировку по полю Ссылка (с типом «Иерархия»).Такой подход позволит имитировать дерево, где верхним уровнем будет владелец, а далее пойдет стандартная иерархия справочника.
Иногда настройки в конфигураторе «слетают» или их нужно задать динамически в зависимости от условий. Рассмотрим пример кода, который можно разместить в процедуре ПриСозданииНаСервере для принудительной установки иерархического режима:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
// Устанавливаем режим отображения таблицы
Элементы.СписокСкладскиеЯчейки.Отображение = ОтображениеТаблицы.Дерево;
// Включаем иерархический просмотр в динамическом списке
СписокСкладскиеЯчейки.ИерархическийПросмотр = Истина;
// Если нужно программно задать основную таблицу
// (обычно задается в метаданных, но можно проверить)
// СписокСкладскиеЯчейки.ОсновнаяТаблица = "Справочник.СкладскиеЯчейки";
КонецПроцедуры
Чтобы дерево выглядело профессионально, нам нужно добавить иконки папок и элементов. В стандартных формах списков это происходит автоматически. Чтобы добиться того же в произвольной обработке, проанализируем настройки колонок таблицы:
Список.ИндексКартинки.БиблиотекаКартинок.ГруппаИЭлемент).Если вы используете произвольный запрос и иконки не подтягиваются, можно добавить вычисляемое поле в запрос или использовать Условное оформление формы. Посмотрим на пример настройки условного оформления:
ЭлементОформления = УсловноеОформление.Элементы.Добавить();
ЭлементОформления.Оформление.УстановитьЗначениеПараметра("Картинка", БиблиотекаКартинок.Группа);
ПолеОформления = ЭлементОформления.Поля.Элементы.Добавить();
ПолеОформления.Поле = Новый ПолеКомпоновкиДанных("Наименование");
ЭлементОтбора = ЭлементОформления.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Список.ЭтоГруппа");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = Истина;
Если динамический список по каким-то причинам не подходит (например, требуется сложная обработка данных «на лету», невозможная в запросе), разработчики выбирают ДеревоЗначений. Однако, как верно заметил автор темы, оно может работать медленно при больших объемах данных. Разберем, как оптимизировать работу с деревом значений.
Рассмотрим методику «ленивой загрузки» (Lazy Loading):
ДеревоЗначений только корневые элементы (те, у которых Родитель.Пустая()).ПриРазворачивании (или ПередРазворачиванием) проверяем, загружены ли данные. Если нет — удаляем фиктивную строку и считываем из базы реальных подчиненных только для этого узла.Такой метод позволяет форме открываться мгновенно, даже если в справочнике десятки тысяч элементов, так как данные передаются с сервера на клиент небольшими порциями.
Для реализации дерева в динамическом списке важно соблюдать три правила: заданная Основная таблица, режим отображения «Дерево» в элементе формы и корректные группировки для подчиненных объектов. Динамический список — это наиболее эффективный инструмент для иерархических списков, так как он обеспечивает оптимальную нагрузку на сервер и сеть за счет постраничного считывания данных.