v8: Универсальное сохранение/восстановление деревьев
Универсальный алгоритм сохранения\восстановления деревьев на форме. | Автор статьи: Violently Последняя редакция №1 от 30.01.07 |
Ключевые слова: Дерево, сохранить, восстановить, записать, построить
В данной статье я предлагаю рассмотреть универсальный алгоритм восстановления деревьев.
Введение:
На начальной стадии моей работы так сложилось, что мне постоянно давали делать документы, у которых на форме необходимо было представлять данные в иерархическом виде. В связи с этим при сохранении документа необходимо было как-то запоминать дерево. Намучавшись вдоволь с индивидуальным для каждого документа алгоритмом, было решено разработать универсальный.
Описание универсального алгоритма сохранения:
Чтобы реализовать алгоритм, потребуется следующее:
1. Предположим, что дерево на форме у Вас уже есть и оно как-то заполняется, либо Вы его заполняете сами – неважно.
2. Добавляем на форму в дерево две колонки, у меня это будет: «ИндексНачало» и «ИндексКонец», они будут иметь строковое представление в 200 символов. (Данные колонки затем рекомендуется просто скрыть, так как они носят чисто служебный характер).
3. Создаем табличную часть у документа, которая будет содержать реквизиты, количество и тип которых будут зависеть от количества и типа колонок на дереве формы. (Грубо говоря, переносим колонки в табличную часть).
4. После чего на процедуре «ПриЗаписи» (вообще по Вашему усмотрению) будем сохранять дерево в табличную часть.
Например, я покажу как это сделано у меня:
4.1. Сначала вызывается процедура «СохранитьДеревья»:
Процедура СохранитьДеревья() ВосстановлениеДерева.Очистить(); //чистим табличную часть СохранитьДерево(ДеревоНаФорме); //вызываем процедуру сохранения КонецПроцедуры
4.2 Сохраняем:
Процедура СохранитьДерево (Дерево) Сч = 0; Для каждого Стр из Дерево.Строки Цикл Индекс = ДеревоНаФорме.Строки.Индекс(Стр); Буква = ВернутьБуквуПоЧислу(Стр.Уровень()); ТекРодитель = Стр.Родитель; Если ТекРодитель = Неопределено Тогда ИндексНачало = "" + Буква + Сч; Приставка = ""; Иначе ИндексНачало = ТекРодитель.ИндексКонец; Приставка = ИндексНачало; КонецЕсли; ИндексКонец = "" + Буква + Сч + Приставка; Стр.ИндексНачало = ИндексНачало; Стр.ИндексКонец = ИндексКонец; // заполнение табличной части СтрП = ВосстановлениеДерева.Добавить(); СтрП.СтатьиКалькуляции = Стр.СтатьиКалькуляции; СтрП.СтруктураИзделий = Стр.СтруктураИзделий; СтрП.ЕдиницыИзмерения = Стр.ЕдиницыИзмерения; СтрП.Количество = Стр.Количество; СтрП.ИндексНачало = ИндексНачало; СтрП.ИндексКонец = ИндексКонец; СохранитьДерево (Стр); Сч = Сч + 1; КонецЦикла; КонецПроцедуры Функция ВернутьБуквуПоЧислу(НомерБуквы) НомерБуквы1 = НомерБуквы + 1; СтрокаБукв = "АБВГДЕЁЖЗИЙКЛМНОПРСТУФХЦЧШЩЪЫЬЭЮЯ"; Если НомерБуквы1 > 33 Тогда НомерБуквы2 = НомерБуквы1 - 33; Буква1 = ВернутьБуквуПоЧислу(НомерБуквы2); Буква = Сред(СтрокаБукв, 1, 1) + Буква1; Иначе Буква = Сред(СтрокаБукв, НомерБуквы1, 1); КонецЕсли; Возврат Буква; КонецФункции
Пункт 4.2. состоит из Процедуры и Функции. Функция нужна для того, чтобы получить код для последующего восстановления дерева.
5. Восстанавливаем дерево, прописав следующий на процедуре «ПриОткрытии»:
Процедура ПриОткрытии() Сп = Новый СписокЗначений(); Сп.Очистить(); Для Каждого Стр Из ВосстановлениеДерева Цикл Если Стр.ИндексНачало = Стр.ИндексКонец Тогда Сп.Добавить(Стр); КонецЕсли; КонецЦикла; Для Каждого СтрСп Из Сп Цикл ВосстановитьДерево(СтрСп.Значение, ДеревоНаФорме); КонецЦикла; КонецПроцедуры Процедура ВосстановитьДерево (ТекСтр, ТекРодитель) Стр = ТекРодитель.Строки.Добавить(); Стр.СтатьиКалькуляции = ТекСтр.СтатьиКалькуляции; Стр.СтруктураИзделий = ТекСтр.СтруктураИзделий; Стр.ЕдиницыИзмерения = ТекСтр.ЕдиницыИзмерения; Стр.Количество = ТекСтр.Количество; Стр.ИндексНачало = ТекСтр.ИндексНачало; Стр.ИндексКонец = ТекСтр.ИндексКонец; Сп = Новый Структура(); Сп.Очистить(); Сп.Вставить("ИндексНачало", ТекСтр.ИндексКонец); Массив = ВосстановлениеДерева.НайтиСтроки(Сп); Для Каждого СтрМ Из Массив Цикл Если СтрМ <> ТекСтр Тогда ВосстановитьДерево (СтрМ, Стр); КонецЕсли; КонецЦикла; КонецПроцедуры
Вот и все. После всех вышеперечисленных действий сохранение должно работать без проблем.