Рассмотрим достаточно нетривиальную, но полезную задачу: как модифицировать стандартную форму отчета на СКД, не создавая для него собственную форму в конфигураторе (поможет расширение для динамического управления элементами форм)? Цель — добавить на форму флажок, который будет переключать основную схему компоновки данных отчета между двумя разными вариантами. При этом важно, чтобы пользовательские настройки, например, введенные даты периода, сохранялись при переключении. Такое программное изменение форм позволяет сохранить гибкость типового решения, расширив его функционал.
Такая необходимость возникает, когда нужно построить отчет по кардинально разным источникам данных, но представить это пользователю как единый отчет с разными режимами — для этого подойдёт обработка для объединения множества отчетов в единый интерфейс. Разберем по шагам, как реализовать такой механизм, используя возможности платформы и, в частности, методы Библиотеки стандартных подсистем (БСП).
Чтобы добавить на форму новый элемент управления, сначала нужно создать для него реквизит формы — для этой задачи есть конструктор интерфейсов и рабочих столов без изменения конфигурации. Стандартные отчеты, использующие БСП, предоставляют специальный механизм событий для управления формой. Нам понадобятся процедуры ОпределитьНастройкиФормы и ПриСозданииНаСервере в модуле объекта отчета.
1. Включаем обработчик события. В модуле отчета нужно объявить процедуру ОпределитьНастройкиФормы, которая сообщит системе, что мы хотим использовать серверное событие создания формы.
Процедура ОпределитьНастройкиФормы(Форма, КлючВарианта, Настройки) Экспорт
// Указываем, что необходимо вызвать обработчик ПриСозданииНаСервере
Настройки.События.ПриСозданииНаСервере = Истина;
КонецПроцедуры
2. Добавляем реквизит и элемент. Теперь в процедуре ПриСозданииНаСервере мы можем изменять состав реквизитов и элементов формы. Подобное добавление реквизитов и элементов формы на управляемые формы можно реализовать динамически прямо во время работы отчета.
Проанализируем код для добавления реквизита типа Булево и связанного с ним флажка на форму.
&НаСервере
Процедура ПриСозданииНаСервере(ЭтаФорма, Отказ, СтандартнаяОбработка) Экспорт
// 1. Готовим массив для новых реквизитов
ДобавляемыеРеквизиты = Новый Массив();
// 2. Создаем описание нового реквизита формы
НовыйРеквизит = Новый РеквизитФормы("ИспользоватьВторуюСхему", Новый ОписаниеТипов("Булево"), , "Использовать вторую схему");
ДобавляемыеРеквизиты.Добавить(НовыйРеквизит);
// 3. Применяем изменения к форме
ЭтаФорма.ИзменитьРеквизиты(ДобавляемыеРеквизиты);
// 4. Создаем новый элемент формы для нашего реквизита
НовыйЭлемент = ЭтаФорма.Элементы.Добавить("ФлажокВыбораСхемы", Тип("ПолеФормы"), ЭтаФорма.Элементы.КоманднаяПанель);
НовыйЭлемент.Вид = ВидПоляФормы.ПолеФлажка;
// 5. Связываем элемент с созданным ранее реквизитом
НовыйЭлемент.ПутьКДанным = "ИспользоватьВторуюСхему";
// 6. Устанавливаем действие, которое будет выполняться при изменении флажка
НовыйЭлемент.УстановитьДействие("ПриИзменении", "ПриИзмененииРежимаОтчета");
КонецПроцедуры
В этом коде мы сначала создали реквизит ИспользоватьВторуюСхему, затем применили его к форме методом ИзменитьРеквизиты. После этого создали элемент типа ПолеФормы с видом ПолеФлажка и связали его с реквизитом через свойство ПутьКДанным. Важный момент — мы сразу назначаем обработчик события ПриИзменении. Это позволит нам реагировать на действия пользователя.
Теперь нужно написать процедуру-обработчик ПриИзмененииРежимаОтчета, которая будет вызываться при клике по нашему флажку. Ее задача — инициировать переформирование отчета.
&НаКлиенте
Процедура ПриИзмененииРежимаОтчета(Элемент)
// Просто вызываем стандартную команду формирования отчета
СкомпоноватьРезультат();
КонецПроцедуры
Эта простая клиентская процедура запускает стандартный механизм формирования отчета. Основная логика по смене схемы будет выполняться на сервере.
Самая важная часть — это подмена схемы компоновки данных перед непосредственным формированием отчета. Идеальное место для этого — событие ПриКомпоновкеРезультата. Здесь мы можем проанализировать значение нашего флажка и на лету подставить нужную схему. Использование подхода, где задействованы две разных схемы в отчете СКД, позволяет кардинально менять логику выборки данных в рамках одного объекта.
Предположим, в вашем отчете есть два макета с типом "Схема компоновки данных": ОсновнаяСхемаКомпоновкиДанных1 и ОсновнаяСхемаКомпоновкиДанных2.
Разберем алгоритм действий в обработчике ПриКомпоновкеРезультата.
ДатаНачала и ДатаОкончания).ИспользоватьВторуюСхему получаем нужный макет.СхемаКомпоновкиДанных отчета выбранную схему.Посмотрим, как это выглядит в коде модуля отчета:
&НаСервере
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
// 1. Сохраняем текущие настройки компоновщика
СохраненныеНастройки = КомпоновщикНастроек.ПолучитьНастройки();
// 2. Определяем, какую схему использовать
ИмяМакетаСхемы = "";
Если ИспользоватьВторуюСхему Тогда
ИмяМакетаСхемы = "ОсновнаяСхемаКомпоновкиДанных2";
Иначе
ИмяМакетаСхемы = "ОсновнаяСхемаКомпоновкиДанных1";
КонецЕсли;
// 3. Получаем выбранную схему из макета и устанавливаем ее как основную
ВыбраннаяСхема = ПолучитьМакет(ИмяМакетаСхемы);
ЭтотОбъект.СхемаКомпоновкиДанных = ВыбраннаяСхема;
// 4. Инициализируем компоновщик настроек новой схемой
КомпоновщикНастроек.Инициализировать(Новый ИсточникДоступныхНастроекКомпоновкиДанных(ЭтотОбъект.СхемаКомпоновкиДанных));
// 5. Загружаем ранее сохраненные настройки
КомпоновщикНастроек.ЗагрузитьНастройки(СохраненныеНастройки);
КонецПроцедуры
Благодаря такому подходу, когда пользователь переключает флажок, отчет переформировывается с новой схемой, но значения параметров остаются на месте.
Стоит упомянуть, что если ваши "разные" отчеты используют один и тот же источник данных, а отличаются только группировками или отборами, то создавать две схемы избыточно. В таких случаях правильнее использовать один макет СКД, но с несколькими вариантами настроек.
Но если источники данных действительно разные, то использование нескольких схем, как описано выше — полностью оправданное решение.