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

27.09.21

Разработка - Универсальные функции

Преобразование Объекта 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, то при использовании таблицы значений (ТЗ) , третья и следующие ТЗ не будут выведены.

 

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

 

 

загрузка XDTO

См. также

Вставляем картинку из буфера обмена (платформа 1С 8.3.24)

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Абонемент ($m)

Задача: вставить картинку из буфера обмена на форму средствами платформы 1С.

1 стартмани

18.03.2024    2949    2    John_d    11    

56

GUID в 1С 8.3 - как с ними быть

Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Пришлось помучиться с GUID-ами немного, решил поделиться опытом, мало ли кому пригодится.

12.02.2024    5265    atdonya    22    

52

Переоткрытие внешних обработок

Универсальные функции Платформа 1С v8.3 Бесплатно (free)

На заключительных этапах, когда идет отладка или доработка интерфейса, необходимо много раз переоткрыть внешний объект. Вот один из способов автоматизации этого.

30.11.2023    4162    ke.92@mail.ru    16    

62

Валидация JSON через XDTO (включая массивы)

WEB-интеграция Универсальные функции Механизмы платформы 1С Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

При работе с интеграциями рано или поздно придется столкнуться с получением JSON файлов. И, конечно же, жизнь заставит проверять файлы перед тем, как записывать данные в БД.

28.08.2023    9603    YA_418728146    6    

143

Печать непроведенных документов для УТ, КА, ERP. Настройка печати по пользователям, документам и печатным формам

Пакетная печать Печатные формы Адаптация типовых решений Универсальные функции Платформа 1С v8.3 1С:ERP Управление предприятием 2 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х Россия Абонемент ($m)

Расширение для программ 1С:Управление торговлей, 1С:Комплексная автоматизация, 1С:ERP, которое позволяет распечатывать печатные формы для непроведенных документов. Можно настроить, каким пользователям, какие конкретные формы документов разрешено печатать без проведения документа.

2 стартмани

22.08.2023    2300    28    progmaster    8    

3

Расширение: Быстрые отборы через буфер [Alt+C] Копировать список, [Alt+V] Вставить список, [Ctrl+C] Копировать из файлов

Инструментарий разработчика Универсальные функции Платформа 1С v8.3 Конфигурации 1cv8 1С:Розница 2 1С:ERP Управление предприятием 2 1С:Бухгалтерия 3.0 1С:Управление торговлей 11 1С:Комплексная автоматизация 2.х 1С:Зарплата и Управление Персоналом 3.x Абонемент ($m)

Копирует в буфер значения из списков, из ячеек отчетов, таблиц, настроек списков, других отборов и вставляет в выбранную настройку отбора. Работает с Объект не найден. Работает как в одной так и между разными базами 1С. Использует комбинации [Alt+C] Копировать список, [Alt+V] Вставить список. Также для копирования данных используется стандартная [Ctrl+C] (например из открытого xls, mxl, doc и т.п. файла скопировать список наименований)

1 стартмани

13.10.2022    16444    144    sapervodichka    112    

130

Система контроля ведения учета [БСП]

Универсальные функции Механизмы типовых конфигураций БСП (Библиотека стандартных подсистем) Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

В данном материале рассмотрим типовой алгоритм подсистемы контроля учета БСП в конфигурациях на примерах.

18.07.2022    7395    quazare    8    

110
Комментарии
Подписаться на ответы Инфостарт бот Сортировка: Древо развёрнутое
Свернуть все
1. user799503 6 10.02.22 12:48 Сейчас в теме
Доделал получение массива из списка. Появилась возможность обработки в списке Объекта XDTO и получения его в виде Таблицы значений, структуры или массива


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