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

Аватар пользователя mykib.org
Файлы для скачивания: 

Продолжение публикации 1С 8. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей. Теперь напишем обработку под управляемые формы.

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

Мы узнаем как в управляемой форме (под тонкий-клиент и web-клиент) реализовать:

Открытие диалога выбора файла с выделением в асинхронную процедуру;

Открытие диалога сохранения файла с выделением в асинхронную процедуру;

Передача файла с клиента на сервер;

Заполнение дерева значений (оперирование с ДанныеФормыДерево, ДанныеФормыКоллекцияЭлементовДерева, ДанныеФормыЭлементДерева);

Передача файла с сервера на клиент.

Создадим управляемую форму обработки, со следующими реквизитами:

Адрес – строка неограниченная

ДеревоНаборов – ДеревоЗначений (и колонки к нему)

РасшифровкаСтроки – Строка, на форме многострочная

 

 

Создадим управляемую форму обработки, со следующими реквизитами

Добавим команды формы и соответствующие клиентские процедуры к ним

 

Добавим команды формы и соответствующие клиентские процедуры к ним

Процедура для кнопки «Заполнить из файла»:

 

//--Открытие диалога выбора файла с выделением в асинхронную процедуру
&НаКлиенте
Процедура ЗаполнитьИзФайла(Команда)
	//Открытие диалога выбора файла
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.ПолноеИмяФайла = "";
	Диалог.Фильтр = "файлы СКД *.xml|*.xml";
	Диалог.МножественныйВыбор = Ложь;
	Диалог.Заголовок = "Выберите файл СКД - ресурс";
	Диалог.Показать(Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение1", ЭтаФорма, Новый Структура("Диалог", Диалог)));
	
КонецПроцедуры

&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение1(ВыбранныеФайлы, ДополнительныеПараметры) Экспорт
	
	Диалог = ДополнительныеПараметры.Диалог;
	
	Если (ВыбранныеФайлы <> Неопределено) Тогда
		МассивФайлов = Диалог.ВыбранныеФайлы;
		Для Каждого ИмяФайла Из МассивФайлов Цикл
			ИсходныйФайл = ИмяФайла;
		КонецЦикла;
		
		Файл = Новый Файл(ИсходныйФайл);
		Файл.НачатьПроверкуСуществования(Новый ОписаниеОповещения("ЗаполнитьИзФайлаЗавершение", ЭтаФорма, Новый Структура("ИсходныйФайл", ИсходныйФайл)));
		
	КонецЕсли;

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

&НаКлиенте
Процедура ЗаполнитьИзФайлаЗавершение(Существует, ДополнительныеПараметры) Экспорт
	
	ИсходныйФайл = ДополнительныеПараметры.ИсходныйФайл;
	
	Если Существует Тогда
		ЗаполнитьТЧ(ИсходныйФайл);//Чтение XML-файла и заполнение дерева наборов
	Иначе
		Сообщить("Не найден файл " + ИсходныйФайл);
	КонецЕсли;

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

{Замечание! Хочу обратить внимание, что данный код можно создать при помощи такой удобной возможности, как рефакторинг кода:

Выделяем процедуру диалога выбора файла

 

 

Процедура КоманднаяПанель1ЗаполнитьИзФайла(Кнопка)
	
	//Открытие диалога выбора файла
	Диалог = Новый ДиалогВыбораФайла(РежимДиалогаВыбораФайла.Открытие);
	Диалог.ПолноеИмяФайла = "";
	Диалог.Фильтр = "файлы СКД *.xml|*.xml";
	Диалог.МножественныйВыбор = Ложь;
	Диалог.Заголовок = "Выберите файл СКД - ресурс";
	Если Диалог.Выбрать() Тогда
		МассивФайлов = Диалог.ВыбранныеФайлы;
	    Для Каждого ИмяФайла Из МассивФайлов Цикл
	        ИсходныйФайл = ИмяФайла;
	    КонецЦикла;
	
		Файл = Новый Файл(ИсходныйФайл);
		Если Файл.Существует() Тогда
			ЗаполнитьТЧ(ИсходныйФайл);//Чтение XML-файла и заполнение дерева наборов
		Иначе
			Сообщить("Не найден файл " + ИсходныйФайл);
		КонецЕсли;
		
	КонецЕсли;
	
КонецПроцедуры

 

 

И воспользовавшись пунктом меню «Текст -> »получаем асинхронный код


1С 8. рефакторинг кода

 

Конец замечания}

В неуправляемых формах, чтобы очистить строки дерева мы использовали

ДеревоНаборов.Строки.Очистить();

 

В управляемых формах это будеть выглядеть следующим образом:

ЭлементыДанныеФормыДерево = ДеревоНаборов.ПолучитьЭлементы();
ЭлементыДанныеФормыДерево.Очистить();

 

Процедура ЗаполнитьТЧ() рекурсивно формирует дерево наборов данных и создает колонки соответствующего элемента формы:

 

&НаКлиенте
Процедура ЗаполнитьТЧ(ИсходныйФайл)
	
	//Очистим строки и колонки дерева наборов
	ЭлементыДанныеФормыДерево = ДеревоНаборов.ПолучитьЭлементы();
	ЭлементыДанныеФормыДерево.Очистить();
	
	ДвоичДанные = Новый ДвоичныеДанные(ИсходныйФайл);
	Адрес = ПоместитьВоВременноеХранилище(ДвоичДанные, УникальныйИдентификатор);
	ЗаполнитьДеревоИзФайлаНаСервере(Адрес);
	
КонецПроцедуры

&НаСервере
Процедура ЗаполнитьДеревоИзФайлаНаСервере(Адрес)
	ДвоичныеДанные = ПолучитьИзВременногоХранилища(Адрес);
	ИмяВременногоФайла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].Элементы);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

 

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

 

Ключевые фразы: