Почему отчет на СКД не реагирует на изменение периода на форме и как это исправить?

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

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

Причина проблемы: особенности программного формирования отчета

Проанализируем типичную ситуацию. В модуле объекта или формы отчета переопределяется стандартное формирование через событие ПриКомпоновкеРезультата. Зачастую разработчик добавляет этот код ради одной мелкой задачи — например, чтобы программно свернуть группировки табличного документа с помощью метода ПоказатьУровеньГруппировокСтрок().

Посмотрим на пример ошибочного кода в модуле отчета:


Процедура ПриКомпоновкеРезультата(ДокументРезультат, ДанныеРасшифровки, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    КомпоновщикМакет = Новый КомпоновщикМакетаКомпоновкиДанных;
    // ОШИБКА: передаются базовые настройки схемы без учета изменений пользователя
    Макет = КомпоновщикМакет.Выполнить(СхемаКомпоновкиДанных, КомпоновщикНастроек.Настройки, ДанныеРасшифровки);
    
    ПроцессорКомпоновки = Новый ПроцессорКомпоновкиДанных;
    ПроцессорКомпоновки.Инициализировать(Макет, , ДанныеРасшифровки);
    
    ПроцессорВывода = Новый ПроцессорВыводаРезультатаКомпоновкиДанныхВТабличныйДокумент;
    ПроцессорВывода.УстановитьДокумент(ДокументРезультат);
    ПроцессорВывода.Вывести(ПроцессорКомпоновки);
    
    ДокументРезультат.ПоказатьУровеньГруппировокСтрок(1);
КонецПроцедуры

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

Решение 1. Использование метода ПолучитьНастройки()

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

Посмотрим на исправленный вариант процедуры:


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

Решение 2. Правильная настройка связи параметров в схеме СКД

Рассмотрим частый сценарий, когда в отчете используются параметры даты начала и окончания для запроса, но пользователю удобнее выбирать единый параметр типа СтандартныйПериод. Чтобы все работало автоматически без написания программного кода, настроим схему компоновки данных по шагам:

  1. Перейдем на вкладку Параметры в схеме компоновки данных.
  2. Создадим параметр ПериодОтчета с типом СтандартныйПериод. Включим его в пользовательские настройки, чтобы он отображался в шапке отчета.
  3. Для параметров запроса НачалоПериода и КонецПериода установим флаг Ограничение доступности (чтобы скрыть их от прямого редактирования пользователем).
  4. В поле Выражение для параметра НачалоПериода укажем: &ПериодОтчета.ДатаНачала.
  5. В поле Выражение для параметра КонецПериода укажем: КонецПериода(&ПериодОтчета.ДатаОкончания, "ДЕНЬ").

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

Решение 3. Программный перенос значений параметров из пользовательской формы

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

Рассмотрим пример кода для данного случая:


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

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

← На главную