При разработке отчетов на базе системы компоновки данных (СКД) разработчики нередко сталкиваются с ситуацией: в схеме настроены параметры периода (например, СтандартныйПериод или НачалоПериода и КонецПериода), пользователь меняет даты на форме отчета, нажимает кнопку формирования, но отчет упорно формируется по старым значениям или вовсе игнорирует ввод. Разберем причины такого поведения и рассмотрим правильные варианты реализации отчета.
Проанализируем типичную ситуацию. В модуле объекта или формы отчета переопределяется стандартное формирование через событие ПриКомпоновкеРезультата. Зачастую разработчик добавляет этот код ради одной мелкой задачи — например, чтобы программно свернуть группировки табличного документа с помощью метода ПоказатьУровеньГруппировокСтрок().
Посмотрим на пример ошибочного кода в модуле отчета:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КомпоновщикМакет = Новый КомпоновщикМакетаКомпоновкиДанных;
// ОШИБКА: передаются базовые настройки схемы без учета изменений пользователя
Макет = КомпоновщикМакет.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
ДокументРезультат.ПоказатьУровеньГруппировокСтрок(1);
КонецПроцедуры
Выясним причину ошибки: свойство КомпоновщикНастроек.Настройки содержит только базовые (исходные) настройки схемы компоновки данных. Когда пользователь меняет параметры, отборы или группировки на форме отчета, эти изменения помещаются в коллекцию КомпоновщикНастроек.ПользовательскиеНастройки. Передавая в метод Выполнить() свойство КомпоновщикНастроек.Настройки напрямую, мы полностью отсекаем все пользовательские правки, сделанные на форме.
Разберем самый простой и корректный способ исправления кода в процедуре ПриКомпоновкеРезультата. Вместо обращения к свойству Настройки необходимо вызвать метод ПолучитьНастройки() объекта КомпоновщикНастроек. Этот метод автоматически объединяет базовые настройки схемы с пользовательскими настройками, переданными с формы.
Посмотрим на исправленный вариант процедуры:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КомпоновщикМакет = Новый КомпоновщикМакетаКомпоновкиДанных;
// Получаем результирующие настройки с учетом пользовательского ввода
НастройкиОтчета = КомпоновщикНастроек.ПолучитьНастройки();
Макет = КомпоновщикМакет.Выполнить(СхемаКомпоновкиДанных, НастройкиОтчета, ДанныеРасшифровки);
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
ДокументРезультат.ПоказатьУровеньГруппировокСтрок(1);
КонецПроцедуры
Рассмотрим частый сценарий, когда в отчете используются параметры даты начала и окончания для запроса, но пользователю удобнее выбирать единый параметр типа СтандартныйПериод. Чтобы все работало автоматически без написания программного кода, настроим схему компоновки данных по шагам:
ПериодОтчета с типом СтандартныйПериод. Включим его в пользовательские настройки, чтобы он отображался в шапке отчета.НачалоПериода и КонецПериода установим флаг Ограничение доступности (чтобы скрыть их от прямого редактирования пользователем).НачалоПериода укажем: &ПериодОтчета.ДатаНачала.КонецПериода укажем: КонецПериода(&ПериодОтчета.ДатаОкончания, "ДЕНЬ").При такой настройке платформа автоматически вычисляет границы дат и передает их в запрос при каждом изменении периода на форме.
Если для отчета создана собственная управляемая форма и на ней размещен отдельный реквизит Период типа СтандартныйПериод, не привязанный напрямую к пользовательским настройкам СКД, установим значения параметров макета вручную перед выводом.
Рассмотрим пример кода для данного случая:
Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
КомпоновщикМакет = Новый КомпоновщикМакетаКомпоновкиДанных;
Макет = КомпоновщикМакет.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.ПолучитьНастройки(), ДанныеРасшифровки);
// Находим параметры в скомпонованном макете и передаем значения
ПараметрНачало = Макет.ЗначенияПараметров.Найти("НачалоПериода");
Если ПараметрНачало <> Неопределено Тогда
ПараметрНачало.Значение = Период.ДатаНачала;
КонецЕсли;
ПараметрКонец = Макет.ЗначенияПараметров.Найти("КонецПериода");
Если ПараметрКонец <> Неопределено Тогда
ПараметрКонец.Значение = ?(ЗначениеЗаполнено(Период.ДатаОкончания), КонецДня(Период.ДатаОкончания), '00010101');
КонецЕсли;
ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);
ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
ПроцессорВывода.Вывести(ПроцессорКомпоновки);
КонецПроцедуры
Важное замечание: создание собственной формы отчета с нуля часто лишает отчет стандартного функционала (подсчет суммы выделенных ячеек, отправка по почте, сохранение вариантов). Поэтому в большинстве случаев рекомендуется использовать типовые формы и решать задачи через метод КомпоновщикНастроек.ПолучитьНастройки().