Каталог решений - Многоуровневая структура из XDTO

Многоуровневая структура из XDTO

Многоуровневая структура из XDTO

В наличии

Преобразование Объекта XDTO в многоуровневую Структуру. Вывод многоуровневой структуры в табличный документ.

Категория:

Описание

Данная публикация развивает тему, поднятую в

https://forum.infostart.ru/forum104/topic194804/

Однако, преобразует не в одноуровневую, а в многоуровневую структуру.

Собственно сам код:

Передаём данные файла:

  Функция ПрочитатьФайлНаСервере(ДанныеФайла,СвернутьПоле="") Экспорт
  
  	ЧтениеДанных = Новый ЧтениеXML;
  	ЧтениеДанных.УстановитьСтроку(ДанныеФайла);
  	ЧтениеДанных.Прочитать();
  	
  	Данные=ФабрикаXDTO.ПрочитатьXML(ЧтениеДанных);
      Если ТипЗнч(Данные)=Тип("ОбъектXDTO") Тогда
          СтруктураРезультат=Новый Структура(); 
          Владелец="";
          ВычСтрока="Структ";
          ЗаписатьОбъектXDTOВСтруктуру(Данные,СтруктураРезультат,Владелец,ВычСтрока,Истина);
      Иначе
          ВызватьИсключение "XDTO. Что-то пошло не так....";
      КонецЕсли; 
  КонецФункции // ПрочитатьФайлНаСервере(ДанныеФайла)
  

Функция, возвращающая структуру. Если не использовать ТаблицуЗначений, то полученную структуру можно смело загружать в JSon

  Функция ПолучитьМассивИзСписка(Список)
      ВремМассив=Новый ТаблицаЗначений;
      АТутСписок=Новый СписокЗначений;
      Для каждого Стр Из Список Цикл
          НовСтр=ВремМассив.Добавить();
          Для каждого ВСтр Из Стр.Свойства() Цикл
              Если ВремМассив.Колонки.Найти(ВСтр.Имя)=Неопределено Тогда
                  ВремМассив.Колонки.Добавить(ВСтр.Имя);
                  Если ВСтр.ВерхняяГраница<>1 Тогда
                      АТутСписок.Добавить(ВСтр.Имя);
                  КонецЕсли; 
              КонецЕсли;
              Если АТутСписок.НайтиПоЗначению(Встр.Имя)=Неопределено Тогда
                  НовСтр[ВСтр.Имя]=Стр.Получить(ВСтр);
              Иначе
                  НовСтр[ВСтр.Имя]=ПолучитьМассивИзСписка(Стр[ВСтр.Имя]);
              КонецЕсли; 
          КонецЦикла; 
      КонецЦикла; 
  	Возврат ВремМассив;
  КонецФункции // ПолучитьМассивИзСписка(Список)
  
  Функция ЗаписатьОбъектXDTOВСтруктуру(Данные,Структ,Владелец,Знач ВычСтрока,ВложеннуюСтруктуруВТЗ=Ложь) Экспорт
      Если ТипЗнч(Данные)=Тип("ОбъектXDTO")=Ложь Тогда
          Сообщить("Это не XDTO");
      	Возврат Новый Структура(); 
      КонецЕсли;
      Коллекция=Данные.Свойства();
      Если Коллекция.Количество()=0 Тогда
          Владелец="";
      	Возврат Новый Структура();
      Иначе
          ВычСтрока=ВычСтрока+Владелец;
      КонецЕсли;
      ТТТ=Вычислить(ВычСтрока);
      н=0;
      Для каждого Элем Из Коллекция Цикл
          н=н+1;
          ТекКлюч=Элем.Имя;
          Если Элем.ВерхняяГраница=1 Тогда
              ЭлемДанные=Данные.Получить(Элем);
              Если ТипЗнч(ЭлемДанные)=Тип("ОбъектXDTO") Тогда
                  Если ТТТ.Свойство(ТекКлюч)=Ложь Тогда
                      Владелец="."+ТекКлюч;
                      ТТТ.Вставить(ТекКлюч,Новый Структура);
                      ТТТ[ТекКлюч]=ЗаписатьОбъектXDTOВСтруктуру(Данные.Получить(Элем),Структ,Владелец,ВычСтрока,ВложеннуюСтруктуруВТЗ);
                  КонецЕсли;
              ИначеЕсли ТипЗнч(Данные.Получить(Элем))=Тип("Строка") Тогда
                  ТТТ.Вставить(ТекКлюч,ЭлемДанные);
              Иначе
                  А=1; //можно установить точку останова и посмотреть, что тут.....
              КонецЕсли;
          Иначе
              АТутСписок=Новый СписокЗначений;
              Если ВложеннуюСтруктуруВТЗ=Истина Тогда
                  ВремМассив=ПолучитьМассивИзСписка(Данные[ТекКлюч]);
              Иначе
                  ВремМассив=Новый Массив;
                  Для каждого Стр Из Данные[ТекКлюч] Цикл
                      ВремСтр=Новый Структура(); 
                      Для каждого ВСтр Из Стр.Свойства() Цикл
                          Если ВСтр.ВерхняяГраница=1 Тогда
                              ВремСтр.Вставить(ВСтр.Имя,Стр.Получить(ВСтр));
                          Иначе
                              ВремСтр.Вставить(ВСтр.Имя,"Если есть желание, то можно дописать"); //если у кого-то список в списке.... может дописать :-)
                          КонецЕсли; 
                      КонецЦикла; 
                      ВремМассив.Добавить(ВремСтр);
                  КонецЦикла; 
              КонецЕсли; 
              ТТТ.Вставить(ТекКлюч,ВремМассив);
          КонецЕсли; 
      КонецЦикла;
      Возврат ТТТ;
  КонецФункции // ЗаписатьОбъектXDTOВСтруктуру(Данные,Структ)

Функция для вывода структуры на печать.

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

При выводе на печать есть ограничение, если у кого-то будет извращение, что списокXDTO, содержит поле со спискомXDTO, в котором будет ещё поле со списком XDTO, то при использовании таблицы значений (ТЗ) , третья и следующие ТЗ не будут выведены.

 

Пример макета:

 

 

has been added to your cart:
Оформление заказа