1С 8. СКД: смена типа «набор данных – запрос» на «набор данных – объект» с сохранением полей

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

Возникла у меня необходимость в существующем отчете на СКД, имеющем набор данных - запрос, изменить тип набора данных с запроса на объект - таблицу значений. Но при смене типа набора данных слетели все поля, роли, ресурсы, оформление – в общем все слетело.

Погуглил и нашел способ – редактирование xml- файла схемы компоновки данных в текстовом редакторе. А почему бы не написать обработку для , которая все сделает сама?

Предлагаю вместе создать такую обработку.

Итак, у нас xml – файл СКД,  в котором присутствует набор данных – запрос (учтем, что в данном файле наборы данных могут быть не только на основании запросов, но и объектов, а также объединения). Файл получен, нажатием в конфигураторе кнопки «Сохранить схему в файл»:

Сохраниение СКД в файл

 

Предлагаю на форме разместить два поля: первое для отображения наборов данных (тип ДеревоЗначений, т.к. объединение тоже может содержать различные наборы данных, то использование таблицы значений нам не подойдет), второе для отображения текста запроса набора данных-запрос(строка неограниченной длины, на форме многострочная):

 

 

Добавим поля на форму

Теперь организуем выбор и обработку файла исходной схемы компоновки данных. Для этого создадим кнопку «Заполнить из файла», назначим ей событие при нажатии:

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

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

Процедура ЗаполнитьДерево(Позиция, НаборыДанных)
	Сч = 0;
	Для Каждого НаборДанных Из НаборыДанных Цикл
		Сч = Сч + 1;
		НовСтр = Позиция.Строки.Добавить();
		ЗаполнитьЗначенияСвойств(НовСтр, НаборДанных);
		НовСтр.Номер = Сч;
		Если ЗначениеЗаполнено(НовСтр.Запрос) Тогда
			НовСтр.ТипНабора = "Запрос";
		ИначеЕсли ЗначениеЗаполнено(НовСтр.ИсточникДанных) Тогда
			НовСтр.ТипНабора = "Объект";
		Иначе
			НовСтр.ТипНабора = "Объединение";
			//Т.к. объединение может содержать различные наборы,
			//то разберем набор-объединение по наборам данных
			ЗаполнитьДерево(НовСтр, НаборДанных.Элементы);
		КонецЕсли;
	КонецЦикла;
КонецПроцедуры

Для того, чтобы в нижней части обработки в поле РасшифровкаСтроки отображался текст запроса текущего набора данных (если, конечно, этот набор даных-запрос) используем событие ПриАктивацииСтроки нашего дерева:

Процедура ДеревоНаборовПриАктивизацииСтроки(Элемент)
	ТекДанные = Элемент.ТекущиеДанные;
	Если ТекДанные.ТипНабора = "Запрос" Тогда
		РасшифровкаСтроки = ТекДанные.Запрос;
	ИначеЕсли ТекДанные.ТипНабора = "Объект" Тогда
		РасшифровкаСтроки = ТекДанные.ИмяОбъекта;
	Иначе
		РасшифровкаСтроки = "";
	КонецЕсли;
КонецПроцедуры

При активации строки

Теперь можно в дереве указать какие наборы заменять (установка флажка в колонке «Пометка» и имя объекта, содержащего данные в колонке «Имя объекта»), например, так:

Выбераем те наборы, которые хотим заменить

Создадим кнопку «Сохранить СКД в файл как…», процедура, вызываемая по нажатию этой кнопки:

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

А вот и сама, так сказать, процедура-гвоздь программы ВыполнитьЗамену():

Процедура ВыполнитьЗамену(ДеревоНаборовСтроки, НовСКДНаборыДанных)
	
	Для Каждого Стр Из ДеревоНаборовСтроки Цикл
		Если Стр.Отметка Тогда
			
			НовыйНабор = НовСКДНаборыДанных.Вставить(Стр.Номер-1, Тип("НаборДанныхОбъектСхемыКомпоновкиДанных"));
			
			СтарыйНабор = НовСКДНаборыДанных[Стр.Номер];
			
			ЗаполнитьЗначенияСвойств(НовыйНабор, СтарыйНабор);
			НовыйНабор.ИмяОбъекта = Стр.ИмяОбъекта;
			Для Каждого СтарыйНаборПоле ИЗ СтарыйНабор.Поля Цикл
				НовПоле = НовыйНабор.Поля.Добавить(ТипЗнч(СтарыйНаборПоле));
				ЗаполнитьЗначенияСвойств(НовПоле ,СтарыйНаборПоле);
			КонецЦикла;
			НовСКДНаборыДанных.Удалить(СтарыйНабор);
			
		Иначе
			Если Стр.ТипНабора = "Объединение" Тогда
				ВыполнитьЗамену(Стр.Строки, НовСКДНаборыДанных[Стр.Номер-1].Элементы);
			КонецЕсли;
		КонецЕсли;
	КонецЦикла;
	
КонецПроцедуры

Наш результат

Все очень просто, Обработка (неуправляемые формы) прилагается – используйте.

При необходимости, не против добавить и на управляемых формах. Удачи…

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

Комментарии

Аватар пользователя mykib.org

<p>http://www.mykib.org/article/1s-8-chast-2-upravlyaemye-formy-skd-smena-tipa-nabor-dannyh-zapros-na-nabor-dannyh-obekt-s</p>