Преобразование дерева значений в таблицу значений и обратно
Хочу поделиться с посетителями сайта своим подходом к преобразованию таблицы значений в дерево значений и обратно.
Вообще, при разработке отраслевой задачи, была необходимость почти во всех документах, выводить информацию в виде дерева и хранить ее в табличных частях документа, а также в интерактивной обработке данных в виде дерева.
Отсюда появился небольшой модуль для расширения возможности работы с деревом значений, хотя и с некоторыми оговорками.
Основной идеей является использование двух ключевых реквизитов/колонок КлючСтроки и КлючСвязи.
Однако они не всегда необходимы. Код, на мой взгляд достаточно «высушен».
Код 1C v 8.х
X
// ПРОЦЕДУРЫ И ФУНКЦИИ ДЛЯ РАБОТЫ С ДЕРЕВОМ ЗНАЧЕНИЙ
// Функция формирует значение нового ключа строки табличной части.
//
// Параметры:
// Дерево - дерево значений
//
Функция ПолучитьНовыйКлючСтрокиДерева(Дерево, СписокКлючей = Неопределено) Экспорт
Если СписокКлючей = Неопределено Тогда
СписокКлючей = Новый СписокЗначений;
СписокКлючей.Добавить(0);
КонецЕсли;
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
СписокКлючей.Добавить(СтрокаДерева.КлючСтроки);
ПолучитьНовыйКлючСтрокиДерева(СтрокаДерева, СписокКлючей);
СписокКлючей.СортироватьПоЗначению(НаправлениеСортировки.Убыв);
МаксКлюч = СписокКлючей[0].Значение + 1;
КонецЦикла;
Возврат МаксКлюч;
КонецФункции // ПолучитьНовыйКлючСтрокиДерева()
// Процедура обновляет ключи связи в дереве значений
//
Процедура ОбновитьКлючиСвязиВДеревеЗначений(Дерево) Экспорт
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
Попытка
СтрокаДерева.КлючСвязи = СтрокаДерева.Родитель.КлючСтроки;
Исключение
СтрокаДерева.КлючСвязи = 0;
КонецПопытки;
ОбновитьКлючиСвязиВДеревеЗначений(СтрокаДерева);
КонецЦикла;
КонецПроцедуры // ОбновитьКлючиСвязиВДеревеЗначений()
// Процедура обновляет ключи связи в дереве значений
//
Процедура ОбновитьКлючиСтрокВДеревеЗначений(Дерево, КлючСтроки = 1) Экспорт
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
СтрокаДерева.КлючСтроки = КлючСтроки;
КлючСтроки = КлючСтроки + 1;
ОбновитьКлючиСтрокВДеревеЗначений(СтрокаДерева, КлючСтроки);
КонецЦикла;
КонецПроцедуры // ОбновитьКлючиСвязиВДеревеЗначений()
// Процедура выгружает данные из дерева значений в таблицу значений
// данные выгружаются только в таблицу со сходным набором реквизитов
//
Функция ВыгрузитьДеревоЗначенийВТаблицуЗначений(Дерево, Таблица = Неопределено) Экспорт
Если Таблица = Неопределено Тогда
Таблица = Новый ТаблицаЗначений;
Для Каждого Колонка Из Дерево.Колонки Цикл
Таблица.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
КонецЕсли;
Для Каждого СтрокаДерева Из Дерево.Строки Цикл
ЗаполнитьЗначенияСвойств(Таблица.Добавить(), СтрокаДерева);
ВыгрузитьДеревоЗначенийВТаблицуЗначений(СтрокаДерева, Таблица);
КонецЦикла;
Возврат Таблица;
КонецФункции //ВыгрузитьДеревоЗначенийВТаблицуЗначений()
// Процедура выгружает данные из таблицы значений в дерево значений
// данные выгружаются только в таблицу со сходным набором реквизитов
//
// Параметры:
//
// КлючСтроки - имя колонки ТаблицыЗначений - уникальный идентификатор
// КлючСвязи - имя колонки ТаблицыЗначений - указатель привязки к строке Дерева,
// своего рода указатель на "Родителя"
//
Функция ВыгрузитьТаблицуЗначенийВДеревоЗначений(Таблица, КлючСтроки = "КлючСтроки", КлючСвязи = "КлючСвязи") Экспорт
Дерево = Новый ДеревоЗначений;
Для Каждого Колонка Из Таблица.Колонки Цикл
Дерево.Колонки.Добавить(Колонка.Имя, Колонка.ТипЗначения);
КонецЦикла;
Для Каждого СтрокаТаблицы Из Таблица Цикл
СтрокаГруппировки = Дерево.Строки.Найти(СтрокаТаблицы[КлючСвязи], КлючСтроки,Истина);
Если СтрокаГруппировки = Неопределено Тогда
ЗаполнитьЗначенияСвойств(Дерево.Строки.Добавить(), СтрокаТаблицы);
Иначе
ЗаполнитьЗначенияСвойств(СтрокаГруппировки.Строки.Добавить(), СтрокаТаблицы);
КонецЕсли;
КонецЦикла;
Возврат Дерево;
КонецФункции //ВыгрузитьТаблицуЗначенийВДеревоЗначений()
// Процедура устанавливает значение во всем дереве значений
//
Процедура УстановитьЗначениеКолонкиДерева(Дерево, Колонка, Значение) Экспорт
Для каждого СтрокаДерева Из Дерево.Строки Цикл
СтрокаДерева[Колонка] = Значение;
УстановитьЗначениеКолонкиДерева(СтрокаДерева, Колонка, Значение);
КонецЦикла;
КонецПроцедуры //УстановитьЗначениеКолонкиДерева()
// Процедура копирует подчиненные строки дерева значений
//
Процедура СкопироватьПодчиненныеСтроки(СтрокаПриемник, СтрокаИсточник)
Для каждого Строка Из СтрокаИсточник.Строки Цикл
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
НоваяСтрока.КлючСвязи = СтрокаПриемник.КлючСтроки;
ЗаполнитьЗначенияСвойств(НоваяСтрока, Строка);
СкопироватьПодчиненныеСтроки(НоваяСтрока, Строка);
КонецЦикла;
КонецПроцедуры // СкопироватьПодчиненныеСтроки()
// Процедура переносит выделенные строки дерева значений в указанную ветку
//
Процедура ПеренестиСтрокиДереваЗначений(СтрокаПриемник, ВыделенныеСтроки) Экспорт
Если НЕ СтрокаПриемник = Неопределено Тогда
МассивСтрок = Новый Массив;
Для Каждого СтрокаПереноса Из ВыделенныеСтроки Цикл
МассивСтрок.Добавить(СтрокаПереноса);
НоваяСтрока = СтрокаПриемник.Строки.Добавить();
СкопироватьПодчиненныеСтроки(НоваяСтрока, СтрокаПереноса);
ЗаполнитьЗначенияСвойств(НоваяСтрока, СтрокаПереноса);
НоваяСтрока.КлючСвязи = СтрокаПриемник.КлючСтроки;
КонецЦикла;
Для Каждого СтрокаДерева Из МассивСтрок Цикл
Если СтрокаДерева.Родитель = Неопределено Тогда
СтрокаДерева.Строки.Удалить(СтрокаДерева);
Иначе
СтрокаДерева.Родитель.Строки.Удалить(СтрокаДерева);
КонецЕсли;
КонецЦикла;
КонецЕсли;
КонецПроцедуры //ПеренестиСтрокиДереваЗначений()
Источник
ДеревоЗначений.Строки
Метод ВыгрузитьКолонку()
Метод ВыгрузитьКолонку() копирует значения из определенной колонки коллекции строк дерева значений в массив. Значения выгружаются в порядке следования индексов строк коллекции.
Доступность
Сервер, толстый клиент, внешнее соединение, мобильное приложение(сервер).
Пример использования
Пример кода с использованием метода ВыгрузитьКолонку() :
//создание нового дерева значений ДеревоЗначений = Новый ДеревоЗначений; //добавляем колонки ДеревоЗначений.Колонки.Добавить("Наименование"); ДеревоЗначений.Колонки.Добавить("КодТовара"); // //. // мСтроки = ДеревоЗначений.Строки.ВыгрузитьКолонку("Наименование"); //или мСтроки = ДеревоЗначений.Строки.ВыгрузитьКолонку(0);
Читайте также:
Источник
Пример преобразования дерева значений в таблицу значений и обратно в 1Cv8
Хочу поделиться с посетителями сайта своим подходом к преобразованию таблицы значений в дерево значений и обратно. Вообще, при разработке отраслевой задачи, была необходимость почти во всех документах, выводить информацию в виде дерева и хранить ее в табличных частях документа, а также в интерактивной обработке данных в виде дерева. Отсюда появился небольшой модуль для расширения возможности работы с деревом значений, хотя и с некоторыми оговорками. Основной идеей является использование двух ключевых реквизитов/колонок КлючСтроки и КлючСвязи. Однако они не всегда необходимы. Код, на мой взгляд достаточно «высушен». Цель публикации — поделиться с новичками опытом.
// Функция формирует значение нового ключа строки табличной части.
//
// Параметры:
// Дерево — дерево значений
//
Функция ПолучитьНовыйКлючСтрокиДерева ( Дерево , СписокКлючей = Неопределено) Экспорт
Если СписокКлючей = Неопределено Тогда
СписокКлючей = Новый СписокЗначений ;
СписокКлючей . Добавить ( 0 );
КонецЕсли;
Для Каждого СтрокаДерева Из Дерево . Строки Цикл
СписокКлючей . Добавить ( СтрокаДерева . КлючСтроки );
ПолучитьНовыйКлючСтрокиДерева ( СтрокаДерева , СписокКлючей );
СписокКлючей . СортироватьПоЗначению ( НаправлениеСортировки . Убыв );
МаксКлюч = СписокКлючей [ 0 ]. Значение + 1 ;
КонецЦикла;
Возврат МаксКлюч ;
// Процедура обновляет ключи связи в дереве значений
//
Процедура ОбновитьКлючиСвязиВДеревеЗначений ( Дерево ) Экспорт
Для Каждого СтрокаДерева Из Дерево . Строки Цикл
Попытка
СтрокаДерева . КлючСвязи = СтрокаДерева . Родитель . КлючСтроки ;
Исключение
СтрокаДерева . КлючСвязи = 0 ;
КонецПопытки;
ОбновитьКлючиСвязиВДеревеЗначений ( СтрокаДерева );
КонецЦикла;
// Процедура обновляет ключи связи в дереве значений
//
Процедура ОбновитьКлючиСтрокВДеревеЗначений ( Дерево , КлючСтроки = 1 ) Экспорт
Для Каждого СтрокаДерева Из Дерево . Строки Цикл
СтрокаДерева . КлючСтроки = КлючСтроки ;
КлючСтроки = КлючСтроки + 1 ;
ОбновитьКлючиСтрокВДеревеЗначений ( СтрокаДерева , КлючСтроки );
КонецЦикла;
// Процедура выгружает данные из дерева значений в таблицу значений
// данные выгружаются только в таблицу со сходным набором реквизитов
//
Функция ВыгрузитьДеревоЗначенийВТаблицуЗначений ( Дерево , Таблица = Неопределено) Экспорт
Если Таблица = Неопределено Тогда
Таблица = Новый ТаблицаЗначений ;
Для Каждого Колонка Из Дерево . Колонки Цикл
Таблица . Колонки . Добавить ( Колонка . Имя , Колонка . ТипЗначения );
КонецЦикла;
КонецЕсли;
Для Каждого СтрокаДерева Из Дерево . Строки Цикл
ЗаполнитьЗначенияСвойств ( Таблица . Добавить (), СтрокаДерева );
ВыгрузитьДеревоЗначенийВТаблицуЗначений ( СтрокаДерева , Таблица );
КонецЦикла;
Возврат Таблица ;
// Процедура выгружает данные из таблицы значений в дерево значений
// данные выгружаются только в таблицу со сходным набором реквизитов
//
// Параметры:
//
// КлючСтроки — имя колонки ТаблицыЗначений — уникальный идентификатор
// КлючСвязи — имя колонки ТаблицыЗначений — указатель привязки к строке Дерева,
// своего рода указатель на «Родителя»
//
Функция ВыгрузитьТаблицуЗначенийВДеревоЗначений ( Таблица , КлючСтроки = «КлючСтроки» , КлючСвязи = «КлючСвязи» ) Экспорт
Дерево = Новый ДеревоЗначений ;
Для Каждого Колонка Из Таблица . Колонки Цикл
Дерево . Колонки . Добавить ( Колонка . Имя , Колонка . ТипЗначения );
КонецЦикла;
Для Каждого СтрокаТаблицы Из Таблица Цикл
СтрокаГруппировки = Дерево . Строки . Найти ( СтрокаТаблицы [ КлючСвязи ], КлючСтроки , Истина );
Если СтрокаГруппировки = Неопределено Тогда
ЗаполнитьЗначенияСвойств ( Дерево . Строки . Добавить (), СтрокаТаблицы );
Иначе
ЗаполнитьЗначенияСвойств ( СтрокаГруппировки . Строки . Добавить (), СтрокаТаблицы );
КонецЕсли;
КонецЦикла;
Возврат Дерево ;
// Процедура устанавливает значение во всем дереве значений
//
Процедура УстановитьЗначениеКолонкиДерева ( Дерево , Колонка , Значение ) Экспорт
Для каждого СтрокаДерева Из Дерево . Строки Цикл
СтрокаДерева [ Колонка ] = Значение ;
УстановитьЗначениеКолонкиДерева ( СтрокаДерева , Колонка , Значение );
КонецЦикла;
// Процедура копирует подчиненные строки дерева значений
//
Процедура СкопироватьПодчиненныеСтроки ( СтрокаПриемник , СтрокаИсточник )
Для каждого Строка Из СтрокаИсточник . Строки Цикл
НоваяСтрока = СтрокаПриемник . Строки . Добавить ();
НоваяСтрока . КлючСвязи = СтрокаПриемник . КлючСтроки ;
ЗаполнитьЗначенияСвойств ( НоваяСтрока , Строка );
СкопироватьПодчиненныеСтроки ( НоваяСтрока , Строка );
КонецЦикла;
// Процедура переносит выделенные строки дерева значений в указанную ветку
//
Процедура ПеренестиСтрокиДереваЗначений ( СтрокаПриемник , ВыделенныеСтроки ) Экспорт
Если НЕ СтрокаПриемник = Неопределено Тогда
МассивСтрок = Новый Массив ;
Для Каждого СтрокаПереноса Из ВыделенныеСтроки Цикл
МассивСтрок . Добавить ( СтрокаПереноса );
НоваяСтрока = СтрокаПриемник . Строки . Добавить ();
СкопироватьПодчиненныеСтроки ( НоваяСтрока , СтрокаПереноса );
ЗаполнитьЗначенияСвойств ( НоваяСтрока , СтрокаПереноса );
НоваяСтрока . КлючСвязи = СтрокаПриемник . КлючСтроки ;
КонецЦикла;
Для Каждого СтрокаДерева Из МассивСтрок Цикл
Если СтрокаДерева . Родитель = Неопределено Тогда
СтрокаДерева . Строки . Удалить ( СтрокаДерева );
Иначе
СтрокаДерева . Родитель . Строки . Удалить ( СтрокаДерева );
КонецЕсли;
КонецЦикла;
КонецЕсли;
Модуль был использован в моей разработке //infostart.ru/public/205664/
Источник