Как в процедуре ПриКомпоновкеРезультата определить, какой вариант отчета СКД используется?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

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

Метод 1: Использование скрытого параметра-маркера

Этот способ считается одним из самых надежных и универсальных, так как он не зависит от того, используется ли Библиотека стандартных подсистем (БСП) или подсистема предопределенных настроек, или формируется ли отчет в фоновом задании. Разберем его по шагам:

  1. Откроем схему компоновки данных и перейдем на вкладку Параметры.
  2. Добавим новый параметр, например, с именем ИмяТекущегоВарианта (тип — Строка).
  3. В каждом варианте отчета на вкладке Настройки установим значение этого параметра, соответствующее названию варианта (например, "Основной", "Краткий", "Подробный").
  4. Важный нюанс: Чтобы пользователь не видел этот технический параметр, в свойствах параметра в СКД снимем галочку Ограничение доступности (чтобы можно было задать значение в настройках варианта), но в пользовательских настройках самого варианта выключим его отображение или просто не будем включать в состав пользовательских настроек.

Теперь проанализируем, как получить это значение в программном коде модуля объекта:


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

КонецПроцедуры

Метод 2: Сопоставление идентификаторов структуры

Рассмотрим ситуацию, когда мы не хотим вносить изменения в параметры СКД. В этом случае мы можем попытаться сопоставить структуру текущих настроек со структурами вариантов, описанных в схеме, что полезно, если в отчете используются две разных схемы в отчете СКД. Выясним причину, почему это работает: каждый вариант в схеме имеет уникальный идентификатор для своих корневых элементов структуры.

Проанализируем пример функции, которая возвращает имя варианта, сравнивая идентификаторы пользовательских настроек:


Функция ПолучитьИмяТекущегоВарианта(СхемаКомпоновки, Компоновщик)
    
    НастройкиКомпоновки = Компоновщик.ПолучитьНастройки();
    
    // Проверяем наличие элементов структуры
    Если НастройкиКомпоновки.Структура.Количество() = 0 Тогда
        Возврат "";
    КонецЕсли;
    
    // Получаем идентификатор пользовательской настройки первой группировки
    ИдТекущегоВарианта = НастройкиКомпоновки.Структура[0].ИдентификаторПользовательскойНастройки;
    
    // Перебираем все варианты, определенные в схеме
    Для Каждого ВариантНастроек Из СхемаКомпоновки.ВариантыНастроек Цикл
        Если ВариантНастроек.Настройки.Структура.Количество() > 0 Тогда
            Если ВариантНастроек.Настройки.Структура[0].ИдентификаторПользовательскойНастройки = ИдТекущегоВарианта Тогда
                Возврат ВариантНастроек.Имя;
            КонецЕсли;
        КонецЕсли;
    КонецЦикла;
    
    Возврат "";
    
КонецФункции

Эту функцию можно вызвать внутри ПриКомпоновкеРезультата, передав СхемаКомпоновкиДанных и КомпоновщикНастроек.

Метод 3: Использование дополнительных свойств (для БСП)

Если ваша конфигурация построена на базе БСП, то подсистема управления отчетами часто сама передает информацию о текущем варианте в компоновщик. Посмотрим на пример проверки таких свойств:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    КлючВарианта = НеОпределено;
    
    // Пытаемся найти ключ варианта в дополнительных свойствах настроек
    Если КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Свойство("КлючВарианта", КлючВарианта) Тогда
        // КлючВарианта содержит программное имя варианта или его UUID
        Если КлючВарианта = "ОсновнойВариант" Тогда
            // Логика для основного варианта
        КонецЕсли;
    ИначеЕсли КомпоновщикНастроек.Настройки.ДополнительныеСвойства.Свойство("ВариантНаименование", КлючВарианта) Тогда
         // Иногда БСП передает представление варианта
         Сообщить("Формируется вариант: " + КлючВарианта);
    КонецЕсли;

КонецПроцедуры

Метод 4: Передача ключа из формы отчета

В случаях, когда используется управляемая форма отчета, мы можем принудительно передать ключ варианта в модуль объекта перед началом компоновки. Рассмотрим, как это реализовать в модуле формы:

  1. В модуле формы переопределим процедуру ПриОбновленииСоставаПользовательскихНастроекНаСервере или обработчик кнопки формирования.
  2. Запишем ЭтаФорма.КлючТекущегоВарианта в дополнительные свойства компоновщика.

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

Затем в модуле объекта в процедуре ПриКомпоновкеРезультата мы сможем прочитать этот ключ из КомпоновщикНастроек.ПользовательскиеНастройки.ДополнительныеСвойства.

Метод 5: Использование пользовательских полей-маркеров

Иногда требуется изменить поведение ресурсов или итогов в зависимости от варианта. Разберем ситуацию: в одном варианте нам нужно исключить данные по определенному складу из итогов, а в другом — нет. Можно использовать "техническое" пользовательское поле.

Добавим в конкретный вариант отчета Пользовательское поле с уникальным заголовок (например, "РежимБезСкладов"). В коде ПриКомпоновкеРезультата выполним обход:


Для Каждого Элемент Из КомпоновщикНастроек.Настройки.ПользовательскиеПоля.Элементы Цикл
    Если Элемент.Заголовок = "РежимБезСкладов" Тогда
        // Мы понимаем, что активен вариант, где добавлено это поле
        // Можем установить значение какого-либо параметра данных программно
        КомпоновщикНастроек.Настройки.ПараметрыДанных.УстановитьЗначениеПараметра("СчитатьИтоги", Ложь);
    КонецЕсли;
КонецЦикла;

Подведем итог: Выбор метода зависит от архитектуры вашего решения. Если отчет типовой и на БСП — проверяйте ДополнительныеСвойства. Если отчет самописный и должен работать везде — используйте Метод 1 (Параметр-маркер), так как он наиболее предсказуем и не требует наличия открытой формы.

← На главную