Создадим управляемую форму обработки, со следующими реквизитами:
- Адрес – строка неограниченная
- ДеревоНаборов – ДеревоЗначений (и колонки к нему)
- РасшифровкаСтроки – Строка, на форме многострочная
Добавим команды формы и соответствующие клиентские процедуры к ним
Процедура для кнопки «Заполнить из файла»:
//--Открытие диалога выбора файла с выделением в асинхронную процедуру
&НаКлиенте
Процедура ЗаполнитьИзФайла(Команда)
//Открытие диалога выбора файла
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.ПолноеИмяФайла = "";
Диалог.Фильтр = "файлы СКД *.xml|*.xml";
Диалог.МножественныйВыбор = Ложь;
Диалог.Заголовок = "Выберите файл СКД - ресурс";
Диалог.Показать(Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение1", ЭтаФорма, Новый Структура("Диалог", Диалог)));
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение1(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Диалог = ДополнительныеПараметры.Диалог;
Если (ВыбранныеФайлы <> Неопределено) Тогда
МассивФайлов = Диалог.ВыбранныеФайлы;
Для Каждого ИмяФайла Из МассивФайлов Цикл
ИсходныйФайл = ИмяФайла;
КонецЦикла;
Файл = Новый Файл(ИсходныйФайл);
Файл.НачатьПроверкуСуществования(Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение", ЭтаФорма, Новый Структура("ИсходныйФайл", ИсходныйФайл)));
КонецЕсли;
КонецПроцедуры
&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение(Существует, ДополнительныеПараметры) Экспорт
ИсходныйФайл = ДополнительныеПараметры.ИсходныйФайл;
Если Существует Тогда
ЗаполнитьТЧ(ИсходныйФайл); //Чтение XML-файла и заполнение дерева наборов
Иначе
Сообщить("Не найден файл " + ИсходныйФайл);
КонецЕсли;
КонецПроцедуры
//--
{Замечание! Хочу обратить внимание, что данный код можно создать при помощи такой удобной возможности, как рефакторинг кода:
Выделяем процедуру диалога выбора файла
Процедура КоманднаяПанель1ЗаполнитьИзФайла(Кнопка)
//Открытие диалога выбора файла
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
Диалог.ПолноеИмяФайла = "";
Диалог.Фильтр = "файлы СКД *.xml|*.xml";
Диалог.МножественныйВыбор = Ложь;
Диалог.Заголовок = "Выберите файл СКД - ресурс";
Если Диалог.Выбрать() Тогда
МассивФайлов = Диалог.ВыбранныеФайлы;
Для Каждого ИмяФайла Из МассивФайлов Цикл
ИсходныйФайл = ИмяФайла;
КонецЦикла;
Файл = Новый Файл(ИсходныйФайл);
Если Файл.Существует() Тогда
ЗаполнитьТЧ(ИсходныйФайл); //Чтение XML-файла и заполнение дерева наборов
Иначе
Сообщить("Не найден файл " + ИсходныйФайл);
КонецЕсли;
КонецЕсли;
КонецПроцедуры
И воспользовавшись пунктом меню «Текст -> Рефакторинг -> Нерекомендуемые синхронное вызовы -> Выделить в асинхронную процедуру» получаем асинхронный код
Конец замечания}
В неуправляемых формах, чтобы очистить строки дерева, мы использовали
ДеревоНаборов.Строки.Очистить();
В управляемых формах это будет выглядеть следующим образом:
ЭлементыДанныеФормыДерево = ДеревоНаборов.ПолучитьЭлементы();
ЭлементыДанныеФормыДерево.Очистить();
Процедура ЗаполнитьТЧ() рекурсивно формирует дерево наборов данных и создает колонки соответствующего элемента формы:
&НаКлиенте
Процедура ЗаполнитьТЧ(ИсходныйФайл)
//Очистим строки и колонки дерева наборов
ЭлементыДанныеФормыДерево = ДеревоНаборов.ПолучитьЭлементы();
ЭлементыДанныеФормыДерево.Очистить();
ДвоичДанные = Новый ДвоичныеДанные(ИсходныйФайл);
Адрес = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
ЗаполнитьДеревоИзФайлаНаСервере(Адрес);
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДеревоИзФайлаНаСервере(Адрес)
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
ДвоичныеДанные.Записать(ИмяВременногоФайлаXML);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяВременногоФайлаXML);
ЧтениеXML.Прочитать();
СКД = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); //Производит чтение значения в формате XML
ЗаполнитьДерево(ДеревоНаборов.ПолучитьЭлементы(), СКД.НаборыДанных); //Рекурсивное построение дерева значений
КонецПроцедуры
&НаСервере
Процедура ЗаполнитьДерево(Позиция, НаборыДанных)
Сч = 0;
Для Каждого НаборДанных Из НаборыДанных Цикл
Сч = Сч + 1;
НовСтр = Позиция.Добавить();
ЗаполнитьЗначенияСвойств(НовСтр, НаборДанных);
НовСтр.Номер = Сч;
Если ЗначениеЗаполнено(НовСтр.Запрос) Тогда
НовСтр.ТипНабора = "Запрос";
ИначеЕсли ЗначениеЗаполнено(НовСтр.ИсточникДанных) Тогда
НовСтр.ТипНабора = "Объект";
Иначе
НовСтр.ТипНабора = "Объединение";
//Т.к. объединение может содержать различные наборы,
//то разберем набор-объединение по наборам данных
ЗаполнитьДерево(НовСтр.ПолучитьЭлементы(), НаборДанных.Элементы);
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Для передачи файла с клиента на сервер используем временное хранилище. На клиенте:
ДвоичДанные = Новый ДвоичныеДанные(ИсходныйФайл);
Адрес = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
ЗаполнитьДеревоИзФайлаНаСервере(Адрес);
На сервере:
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
ДвоичныеДанные.Записать(ИмяВременногоФайлаXML);
Для вывода текста запроса в поле Расшифровка строки в управляемой форме изменим путь к данным элемента «РасшифровкаСтроки»:
Процедура для ранее созданной кнопке «Сохранить файл…»
&НаКлиенте
Процедура СохранитьВФайл(Команда)
Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Сохранение);
Диалог.ПолноеИмяФайла = "";
Диалог.Фильтр = "файлы СКД *.xml|*.xml";
Диалог.МножественныйВыбор = Ложь;
Диалог.Заголовок = "Файл СКД исправленный";
Диалог.Показать(Новый ОписаниеОповещения("СохранитьВФайлЗавершение", ЭтаФорма, Новый Структура("Диалог", Диалог)));
КонецПроцедуры
&НаКлиенте
Процедура СохранитьВФайлЗавершение(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
Диалог = ДополнительныеПараметры.Диалог;
Если (ВыбранныеФайлы <> Неопределено) Тогда
МассивФайлов = Диалог.ВыбранныеФайлы;
Для Каждого ИмяФайла Из МассивФайлов Цикл
КоррФайл = ИмяФайла;
КонецЦикла;
НовыйАдрес = ВыполнитьЗаменуНаСервере();
ДвоичныеДанные = ПолучитьИзВременногоХранилища(НовыйАдрес);
ДвоичныеДанные.Записать(КоррФайл);
КонецЕсли;
КонецПроцедуры
&НаСервере
Функция ВыполнитьЗаменуНаСервере()
ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
ИмяВременногоФайлаXML = ПолучитьИмяВременногоФайла("xml");
ДвоичныеДанные.Записать(ИмяВременногоФайлаXML);
ЧтениеXML = Новый ЧтениеXML;
ЧтениеXML.ОткрытьФайл(ИмяВременногоФайлаXML);
ЧтениеXML.Прочитать();
СКД = СериализаторXDTO.ПрочитатьXML(ЧтениеXML); //Производит чтение значения в формате XML
НовСКД = Новый СхемаКомпоновкиДанных;
НовСКД = СКД;
ВыполнитьЗамену(ДеревоНаборов.ПолучитьЭлементы(), НовСКД.НаборыДанных);
НовыйФайл = ПолучитьИмяВременногоФайла("xml");
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.ОткрытьФайл(НовыйФайл);
СериализаторXDTO.ЗаписатьXML(ЗаписьXML, НовСКД);
ЗаписьXML.Закрыть();
ДвоичДанные = Новый ДвоичныеДанные(НовыйФайл);
АдресВозвр = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
Возврат АдресВозвр;
КонецФункции
&НаСервере
Процедура ВыполнитьЗамену(ДеревоНаборовСтроки, НовСКДНаборыДанных)
Для Каждого Стр Из ДеревоНаборовСтроки Цикл
Если Стр.Отметка Тогда
НовыйНабор = НовСКДНаборыДанных.Вставить(Стр.Номер - 1, Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
СтарыйНабор = НовСКДНаборыДанных[Стр.Номер];
ЗаполнитьЗначенияСвойств(НовыйНабор, СтарыйНабор);
НовыйНабор.ИмяОбъекта = Стр.ИмяОбъекта;
Для Каждого СтарыйНаборПоле ИЗ СтарыйНабор.Поля Цикл
НовПоле = НовыйНабор.Поля.Добавить(ТипЗнч(СтарыйНаборПоле));
ЗаполнитьЗначенияСвойств(НовПоле, СтарыйНаборПоле);
КонецЦикла;
НовСКДНаборыДанных.Удалить(СтарыйНабор);
Иначе
Если Стр.ТипНабора = "Объединение" Тогда
ВыполнитьЗамену(Стр.ПолучитьЭлементы(), НовСКДНаборыДанных[Стр.Номер - 1].Элементы);
КонецЕсли;
КонецЕсли;
КонецЦикла;
КонецПроцедуры
Обработка прилагается. Надеюсь, что материал кому-то будет полезен. Всего хорошего…