gifts2017

1С 8. Часть 2 - Управляемые формы. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей

Опубликовал Владимир Лучинский (Luchik) в раздел Программирование - Практика программирования

Продолжение публикации "1С 8. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей" http://infostart.ru/public/405762/ . Теперь напишем обработку под управляемые формы. Мы узнаем как в управляемой форме (под тонкий-клиент и 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].Элементы);

                       КонецЕсли;

               КонецЕсли;

        КонецЦикла;

        

КонецПроцедуры

Обработка прилагается. Надеюсь, что материал кому-то будет полезен. Всего хорошего…

Скачать файлы

Наименование Файл Версия Размер Кол. Скачив.
Обработка: Управляемые формы. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей
.epf 9,10Kb
08.10.15
1
.epf 9,10Kb 1 Скачать

См. также

Подписаться Добавить вознаграждение
В этой теме еще нет сообщений.
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа