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

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

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

Понимание контекста выполнения

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

Способ 1: Использование реквизитов объекта отчета

Это один из самых простых и надежных способов, упомянутый в обсуждении. Мы создаем реквизит не только на форме, но и в самом объекте метаданных отчета.

Рассмотрим по шагам:

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

В модуле объекта значение будет доступно через обращение к свойствам самого объекта:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    
    // Получаем значение напрямую из реквизита объекта
    ЗначениеДляЛогики = ЭтотОбъект.ДополнительноеУсловие;
    
    Если ЗначениеЗаполнено(ЗначениеДляЛогики) Тогда
        // Выполняем программную модификацию настроек или запроса
    КонецЕсли;
    
КонецПроцедуры

Преимущество: Данные гарантированно сохраняются при передаче объекта между клиентом и сервером (сериализуются).

Способ 2: Использование параметров Схемы компоновки данных

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

Проанализируем алгоритм:

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

Пример кода в модуле формы перед формированием:


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

В процедуре ПриКомпоновкеРезультата в модуле объекта мы сможем прочитать этот параметр так:


ЗначениеПараметра = КомпоновщикНастроек.Настройки.ПараметрыДанных.НайтиЗначениеПараметра(Новый ПараметрКомпоновкиДанных("НашСпециальныйПараметр")).Значение;

Способ 3: Дополнительные свойства настроек компоновки

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

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

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


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

Теперь в модуле объекта в процедуре ПриКомпоновкеРезультата мы просто извлекаем это значение:


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

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

Способ 4: Передача сложных структур через временное хранилище

Посмотрим на более сложный случай. Допустим, на форме есть ТаблицаЗначений, которую пользователь заполнил вручную, и ее нужно использовать как источник данных или фильтр в модуле объекта. Таблицу нельзя просто поместить в параметры или свойства напрямую из-за ограничений сериализации в некоторых контекстах.

Выполним следующие шаги:

  1. В модуле формы помещаем таблицу во временное хранилище и получаем адрес (строку).
  2. Передаем этот адрес в ДополнительныеСвойства компоновщика (как в Способе 3).
  3. В модуле объекта извлекаем таблицу по адресу.

Пример реализации:


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

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

Резюме и рекомендации

Мы проанализировали основные методы передачи данных между формой и модулем. Подведем итоги, чтобы выбрать оптимальный вариант для вашей задачи:

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

← На главную