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