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