Как в управляемых формах передать значение с формы в модуль объекта отчета при компоновке результата

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

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

Проанализируем архитектурную причину этого поведения и рассмотрим правильные варианты решения задачи.

Почему нельзя просто обратиться к форме из модуля объекта

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

Разберем основные надежные способы передачи данных с управляемой формы в процедуру ПриКомпоновкеРезультата.

Способ 1. Использование стандартных параметров схемы компоновки данных (Рекомендуемый)

Если данные представляют собой список значений для отбора или фильтрации, наиболее правильным подходом является использование параметров самой СКД:

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

Посмотрим на пример извлечения параметра в модуле объекта:


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

Способ 2. Создание реквизита объекта отчета

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

  1. В дереве метаданных у объекта Отчет добавляем реквизит с типом СписокЗначений.
  2. На управляемой форме размещаем элемент, привязанный к пути Отчет.НашРеквизит.
  3. При нажатии кнопки формирования платформа автоматически сериализует реквизиты объекта и передаст их на сервер.
  4. В модуле объекта значение доступно напрямую через свойство ЭтотОбъект.НашРеквизит (или просто по имени реквизита).

Способ 3. Передача через свойство «ДополнительныеСвойства» настроек компоновщика

Если требуется передать динамические данные без изменения состава метаданных объекта, воспользуемся коллекцией ДополнительныеСвойства компоновщика настроек. Это платформенная структура, которая автоматически передается вместе с настройками СКД на сервер.

В модуле формы перехватываем серверное событие (например, ПриЗагрузкеВариантаНаСервере или обработчик команды формирования):


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

Затем в модуле объекта считываем переданную структуру:


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

Способ 4. Программная инициализация формирования из формы

Если формирование отчета вызывается программно через собственную кнопку на форме, можно получить объект отчета на сервере, заполнить его свойство ДополнительныеСвойства и вызвать метод формирования:


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

Внутри процедуры ПриКомпоновкеРезультата модуль объекта сможет обратиться к этим данным через свойство ЭтотОбъект.ДополнительныеСвойства.

Важное замечание: все передаваемые типы данных (элементы списка значений) должны поддерживать сериализацию платформой 1С (ссылочные типы, примитивные типы, структуры, массивы и таблицы значений).

← На главную