Продолжение публикации 1С 8. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей [1]. Теперь напишем обработку [2] под управляемые формы.
Мы узнаем как в управляемой форме (под тонкий-клиент и web-клиент) реализовать:
Открытие диалога выбора файла с выделением в асинхронную процедуру;
Открытие диалога сохранения файла с выделением в асинхронную процедуру;
Передача файла с клиента на сервер;
Заполнение дерева значений (оперирование с ДанныеФормыДерево, ДанныеФормыКоллекцияЭлементовДерева, ДанныеФормыЭлементДерева);
Передача файла с сервера на клиент.
Создадим управляемую форму обработки, со следующими реквизитами:
Адрес – строка неограниченная
ДеревоНаборов – ДеревоЗначений (и колонки к нему)
РасшифровкаСтроки – Строка, на форме многострочная
Добавим команды формы и соответствующие клиентские процедуры к ним
Процедура для кнопки «Заполнить из файла»:
//--Открытие диалога выбора файла с выделением в асинхронную процедуру &НаКлиенте Процедура ЗаполнитьИзФайла(Команда) //Открытие диалога выбора файла Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие); Диалог.ПолноеИмяФайла = ""; Диалог.Фильтр = "файлы СКД *.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].Элементы); КонецЕсли; КонецЕсли; КонецЦикла; КонецПроцедуры
Обработка [2] прилагается. Надеюсь, что материал кому-то будет полезен. Всего хорошего…
Ссылки
[1] https://www.mykib.org/article/1s-8-skd-smena-tipa-nabor-dannyh-zapros-na-nabor-dannyh-obekt-s-sohraneniem-poley
[2] https://www.mykib.org/article/den-devyatyy-integriroval-samyy-bolshoy-katalog-razrabotok-dlya-platformy-1s
[3] https://www.mykib.org/tags/1s-8
[4] https://www.mykib.org/sites/default/files/downloads/uprsmenanaboradannuh.zip