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