Несколько схем данных в одном отчете 1C СКД

Приветствую, мои маленькие любители длинных запросов … и отчетов 1C на СКД.
Сегодня мы на готовом примере рассмотрим следующую задачу: использовать несколько схем данных в одном отчете СКД.
Стоить заметить, что данная реализация не является единственно возможной и не претендует на «истину в последней инстанции». Выбор конкретного способа определяется нюансами конкретной задачи.
Синтетический пример будет реализован в демо-конфигурации Управление торговлей, редакция 11.

  1. Для начала создадим внешний отчет и добавим его реквизит ИмяМакета, тип Строка. В данном реквизите мы будем хранить имя текущего активного макета. Оно нам потребуется при формировании отчета.
  2. Добавим форму отчета. Она необходима для выбора активного макета. Данную форму можно (и нужно) скопировать из состава БСП, ОбщиеФормы — ФормаОтчета. Так мы получим все возможности типовых отчетов СКД с минимальным затратами (хотя и потребуются некоторые доработки), но автоматически генерируемая форма также подойдет.
  3. Добавим 2 макета, тип СхемаКомпоновкиДанных.
    Первый макет СхемаПроизводственныйКалендарь, куда выберем данные из регистра ДанныеПроизводственногоКалендаря с отбором по параметру &Дата.
    Второй макет СхемаФизЛица, куда выберем данные из справочника ФизическиеЛица с отбором по полу
    Как видим, ни параметры, ни поля, ни данные в этих макетах не совпадают. Укажем использование обоих параметров «Всегда» и добавим их для наглядности в пользовательские настройки.
    Стоит заметить, что мы не указываем основную схему в отчете.

Заготовка отчета готова. Теперь перейдем непосредственно к коду выбора, смены и формирования макета

Для начала необходимо в процедуре формы ПриСозданииНаСервере нарисовать кнопку, заполнить список макетов и выбрать один из макетов в качестве «начального».

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

Вот так это выглядит на форме:

Затем пропишем обработчик для команды «ВыбратьМакет».

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

&НаКлиенте
//обработчик выбора макета
Процедура ВыбратьМакетЗавершение(РезультатВыбора, ДопПараметры) Экспорт
	Если РезультатВыбора <> Неопределено Тогда
		ВыбратьМакетЗавершениеНаСервере(Новый Структура("Значение, Представление", РезультатВыбора.Значение, РезультатВыбора.Представление));
	КонецЕсли;
КонецПроцедуры

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

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

Как видим, пользовательские отборы при смене макета так же изменились.

Остается лишь подменить стандартную процедуру формирования отчета. Для этого открываем модуль объекта и формируем СКД программно в процедуре ПриКомпоновкеРезультата.

Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
	СтандартнаяОбработка = Ложь;
	
	СхемаКомпоновки = ЭтотОбъект.ПолучитьМакет(ЭтотОбъект.ИмяМакета);
	Настройки = КомпоновщикНастроек.ПолучитьНастройки();
	
	КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных;
	МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки, ДанныеРасшифровки, , Тип("ГенераторМакетаКомпоновкиДанных"));
	
	ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки,,ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных);
КонецПроцедуры

Таким образом, мы получили два несвязанных макета СКД в одном внешнем отчете, между которыми пользователь может произвольно переключаться.

 

Comments

So empty here ... leave a comment!

Добавить комментарий

Sidebar