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