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