Несколько схем данных в одном отчете 1C СКД
Приветствую, мои маленькие любители длинных запросов … и отчетов 1C на СКД.
Сегодня мы на готовом примере рассмотрим следующую задачу: использовать несколько схем данных в одном отчете СКД.
Стоить заметить, что данная реализация не является единственно возможной и не претендует на «истину в последней инстанции». Выбор конкретного способа определяется нюансами конкретной задачи.
Синтетический пример будет реализован в демо-конфигурации Управление торговлей, редакция 11.
- Для начала создадим внешний отчет и добавим его реквизит ИмяМакета, тип Строка. В данном реквизите мы будем хранить имя текущего активного макета. Оно нам потребуется при формировании отчета.
- Добавим форму отчета. Она необходима для выбора активного макета. Данную форму можно (и нужно) скопировать из состава БСП, ОбщиеФормы — ФормаОтчета. Так мы получим все возможности типовых отчетов СКД с минимальным затратами (хотя и потребуются некоторые доработки), но автоматически генерируемая форма также подойдет.
- Добавим 2 макета, тип СхемаКомпоновкиДанных.
Первый макет СхемаПроизводственныйКалендарь, куда выберем данные из регистра ДанныеПроизводственногоКалендаря с отбором по параметру &Дата.
Второй макет СхемаФизЛица, куда выберем данные из справочника ФизическиеЛица с отбором по полу
Как видим, ни параметры, ни поля, ни данные в этих макетах не совпадают. Укажем использование обоих параметров «Всегда» и добавим их для наглядности в пользовательские настройки.
Стоит заметить, что мы не указываем основную схему в отчете.
Заготовка отчета готова. Теперь перейдем непосредственно к коду выбора, смены и формирования макета
Для начала необходимо в процедуре формы ПриСозданииНаСервере нарисовать кнопку, заполнить список макетов и выбрать один из макетов в качестве «начального».
&НаСервере Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка) //Заголовок будет отражать псевдоним текущего макета ЭтаФорма.АвтоЗаголовок = Ложь; //нарисуем кнопку Кнопка = Элементы.Добавить("ВыбратьМакет", Тип("КнопкаФормы"), Элементы.ОсновнаяКоманднаяПанель); Кнопка.Вид = ВидКнопкиФормы.КнопкаКоманднойПанели; Кнопка.ИмяКоманды = "ВыбратьМакет"; //заполним список макетов //макеты отбираем строго по типу СхемаКомпоновкиДанных, дабы в список не попали печатные макеты, двоичные данные и прочее ОтчетОбъект = РеквизитФормыВЗначение("Отчет"); СписокСхем.Очистить(); Для Каждого Макет из ОтчетОбъект.Метаданные().Макеты Цикл Если Макет.ТипМакета = Метаданные.СвойстваОбъектов.ТипМакета.СхемаКомпоновкиДанных Тогда СписокСхем.Добавить(Макет.Имя, Макет.Синоним); КонецЕсли; КонецЦикла; Если СписокСхем.Количество() = 0 Тогда Отказ = Истина; Возврат; КонецЕсли; //выберем первый из макетов в качестве "начального" ВыбратьМакетЗавершениеНаСервере(Новый Структура("Значение, Представление", СписокСхем[0].Значение, СписокСхем[0].Представление)); КонецПроцедуры
Вот так это выглядит на форме:
Затем пропишем обработчик для команды «ВыбратьМакет».
&НаКлиенте //обработчик кнопки "Выбрать макет" Процедура ВыбратьМакет(Команда) Оповещение = Новый ОписаниеОповещения("ВыбратьМакетЗавершение", ЭтаФорма); //не будем перегружать форму полями, привяжем диалог выбора макета к основной командной панели формы //она появится под стандартной кнопкой Сформировать ПоказатьВыборИзСписка(Оповещение, СписокСхем, Элементы.ОсновнаяКоманднаяПанель); КонецПроцедуры &НаКлиенте //обработчик выбора макета Процедура ВыбратьМакетЗавершение(РезультатВыбора, ДопПараметры) Экспорт Если РезультатВыбора <> Неопределено Тогда ВыбратьМакетЗавершениеНаСервере(Новый Структура("Значение, Представление", РезультатВыбора.Значение, РезультатВыбора.Представление)); КонецЕсли; КонецПроцедуры &НаСервере //процедура, которая выполняет непосредственное переключение активного макета Процедура ВыбратьМакетЗавершениеНаСервере(РезультатВыбора) //обновим заголовок формы именем текущего макета ЭтаФорма.Заголовок = "Отчет с несколькими схемами: " + РезультатВыбора.Представление; //запомним имя выбранного макета Отчет.ИмяМакета = РезультатВыбора.Значение; //получим саму схему СКД = РеквизитФормыВЗначение("Отчет").ПолучитьМакет(РезультатВыбора.Значение); //поместим в временное хранилище макет, иначе источник настроек его не переварит АдресВремХран = ПоместитьВоВременноеХранилище(СКД, Новый УникальныйИдентификатор); //инициализируем настройки по умолчанию ИсточникНастроек = Новый ИсточникДоступныхНастроекКомпоновкиДанных(АдресВремХран); Отчет.КомпоновщикНастроек.Инициализировать(ИсточникНастроек); Отчет.КомпоновщикНастроек.ЗагрузитьНастройки(СКД.НастройкиПоУмолчанию); КонецПроцедуры
Думаю, из построчного комментария к листингу кода все предельно понятно. Самый интересный момент, это «подмена» пользовательских настроек настройками по умолчанию из схемы. Для этого используется объект ИсточникДоступныхНастроекКомпоновкиДанных. В результате инициализации компоновщика настроек будут заменены все пользовательские настройки, а именно отборы, группировки, выбранные поля и т.д.
Как видим, пользовательские отборы при смене макета так же изменились.
Остается лишь подменить стандартную процедуру формирования отчета. Для этого открываем модуль объекта и формируем СКД программно в процедуре ПриКомпоновкеРезультата.
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка) СтандартнаяОбработка = Ложь; СхемаКомпоновки = ЭтотОбъект.ПолучитьМакет(ЭтотОбъект.ИмяМакета); Настройки = КомпоновщикНастроек.ПолучитьНастройки(); КомпоновщикМакета = Новый КомпоновщикМакетаКомпоновкиДанных; МакетКомпоновки = КомпоновщикМакета.Выполнить(СхемаКомпоновки, Настройки, ДанныеРасшифровки, , Тип("ГенераторМакетаКомпоновкиДанных")); ПроцессорКомпоновкиДанных = Новый ПроцессорКомпоновкиДанных; ПроцессорКомпоновкиДанных.Инициализировать(МакетКомпоновки,,ДанныеРасшифровки); ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент; ПроцессорВывода.УстановитьДокумент(ДокументРезультат); ПроцессорВывода.Вывести(ПроцессорКомпоновкиДанных); КонецПроцедуры
Таким образом, мы получили два несвязанных макета СКД в одном внешнем отчете, между которыми пользователь может произвольно переключаться.
Comments
So empty here ... leave a comment!