Преобразование дерева значений в таблицу значений и обратно

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

Дерево значений в таблицу значений

Дано: дерево значений (2 колонки) и таблица значений (4 колонки). Две дополнительные колонки в таблице значений нужны для обратного преобразования, если оно не требуется то и колонки не нужны.

Код выглядит так:

&НаСервере
Процедура ВТЗНаСервере()
тДерево = РеквизитФормыВЗначение(«Дерево»);
тТаблица = РеквизитФормыВЗначение(«Таблица»);
ПреобразоватьВТЗРекурсия(тДерево, тТаблица, Новый УникальныйИдентификатор(«00000000-0000-0000-0000-000000000000»));
тДерево.Строки.Очистить();
ЗначениеВРеквизитФормы(тТаблица, «Таблица»);
ЗначениеВРеквизитФормы(тДерево, «Дерево»);
КонецПроцедуры

&НаСервере
Процедура ПреобразоватьВТЗРекурсия(тДерево, тТаблица, ГУИД)
Для Каждого тСтр Из тДерево.Строки Цикл
нСтр = тТаблица.Добавить();
нСтр.Колонка1 = тСтр.Колонка1;
нСтр.Колонка2 = тСтр.Колонка2;
нСтр.Родитель = ГУИД;
нСтр.ГУИД = Новый УникальныйИдентификатор();
Если тСтр.Строки.Количество()>0 Тогда
ПреобразоватьВТЗРекурсия(тСтр, тТаблица, нСтр.ГУИД);
КонецЕсли;
КонецЦикла;

В колонку «ГУИД» таблицы значений записывается уникальный идентификатор строки (он просто генерируется), а в колонку «Родитель» записывается уникальный идентификатор строки-родителя (для строк верхнего уровня — нулевой уникальный идентификатор).

Таблица значений в дерево значений

Обратное преобразование производится при помощи двух лишних колонок («ГУИД» и «Родитель») если из таблицы значений была удалена какая-то строка, то все подчиненные ей строки также будут удалены.

Код выглядит так:

&НаСервере
Процедура ВДЗНаСервере()
тДерево = РеквизитФормыВЗначение(«Дерево»);
тТаблица = РеквизитФормыВЗначение(«Таблица»);
ПреобразоватьВДЗРекурсия(тДерево, тТаблица, Новый УникальныйИдентификатор(«00000000-0000-0000-0000-000000000000»));
тТаблица.Очистить();
ЗначениеВРеквизитФормы(тТаблица, «Таблица»);
ЗначениеВРеквизитФормы(тДерево, «Дерево»);
КонецПроцедуры

&НаСервере
Процедура ПреобразоватьВДЗРекурсия(тДерево, тТаблица, ГУИД)
тПоиск = Новый Структура(«Родитель», ГУИД);
тМассив = тТаблица.НайтиСтроки(тПоиск);
Для Каждого тСтр Из тМассив Цикл
нСтр = тДерево.Строки.Добавить();
нСтр.Колонка1 = тСтр.Колонка1;
нСтр.Колонка2 = тСтр.Колонка2;
ПреобразоватьВДЗРекурсия(нСтр, тТаблица, тСтр.ГУИД);
КонецЦикла;
КонецПроцедуры

Работу приведенного выше кода можно посмотреть в обработке