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