Почему не передается параметр отбора в универсальный отчет 1С и как это исправить?

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

В процессе разработки в среде 1С:Предприятие на обычных формах (например, в таких конфигурациях, как "Управление торговлей, редакция 10.3", "Управление производственным предприятием, редакция 1.3" или "Комплексная автоматизация, редакция 1.1") часто возникает задача программного открытия отчетов с уже заполненными параметрами отбора. Разработчики нередко сталкиваются с ситуацией, когда код по установке отборов написан без синтаксических ошибок, однако при открытии формы отчета параметры отбора оказываются пустыми или сбрасываются к значениям по умолчанию.

В этой статье мы подробно разберем, почему возникает эта проблема, проанализируем жизненный цикл Универсального отчета и построителя отчетов, а также рассмотрим правильный алгоритм передачи параметров отбора.

Анализ исходного кода и выявление ключевых ошибок

Рассмотрим стандартный пример кода, который часто пишут начинающие разработчики для программного открытия отчета с установкой отбора по конкретному контрагенту:


ОтчетКонтрагента = Отчеты.ПрайсЛистПоКонтрагенту.Создать();
            
ОтчетКонтрагента.УстановитьНачальныеНастройки();
            
ЭлементОтбора = ОтчетКонтрагента.УниверсальныйОтчет.ПостроительОтчета.Отбор["Контрагент"];
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = ЭлементыФормы.СправочникСписок.ТекущиеДанные.Ссылка;

ОтчетКонтрагента.УниверсальныйОтчет.мВосстанавливатьНастройкиПриОткрытии = Ложь;
            
ФормаОтчета = Отчеты.ПрайсЛистПоКонтрагенту.ПолучитьФорму();
ФормаОтчета.Открыть();
ФормаОтчета.ОбновитьОтчет();

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

Причина первая: Создание нового экземпляра объекта вместо использования существующего

Самая очевидная ошибка кроется в строке получения формы отчета:

ФормаОтчета = Отчеты.ПрайсЛистПоКонтрагенту.ПолучитьФорму();

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

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

Чтобы избежать этой ошибки, получать форму необходимо строго от уже созданного и настроенного объекта:

ФормаОтчета = ОтчетКонтрагента.ПолучитьФорму();

В этом случае платформа вернет форму, которая жестко связана с конкретным экземпляром объекта ОтчетКонтрагента, содержащим наши настройки.

Причина вторая: Сброс настроек при открытии формы (Жизненный цикл формы)

Даже если мы исправим первую ошибку и получим форму от правильного объекта, отборы все равно могут не примениться или сброситься при вызове метода Открыть(). Давайте разберем по шагам, что происходит в этот момент:

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

Правильный алгоритм программной настройки Универсального отчета

Чтобы обойти механизмы автоматического сброса настроек при инициализации формы Универсального отчета, мы должны изменить порядок выполнения действий. Наиболее надежный и проверенный временем способ в обычных формах заключается в том, чтобы **сначала открыть форму**, дождавшись завершения всех ее внутренних процедур инициализации, и **только после этого принудительно установить отборы** и сформировать отчет.

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


// 1. Создаем объект отчета
ОтчетКонтрагента = Отчеты.ПрайсЛистПоКонтрагенту.Создать();

// 2. Получаем форму, связанную именно с этим объектом
ФормаОтчета = ОтчетКонтрагента.ПолучитьФорму();

// 3. Открываем форму отчета на экране. 
// В этот момент отрабатывают все процедуры инициализации и сброса настроек.
ФормаОтчета.Открыть();

// 4. Теперь, когда форма открыта и настройки инициализированы стандартными значениями,
// мы программно переопределяем нужный нам отбор в открытой форме.
УниверсальныйОтчетОбъект = ФормаОтчета.УниверсальныйОтчет;
ЭлементОтбора = УниверсальныйОтчетОбъект.ПостроительОтчета.Отбор["Контрагент"];

// Включаем использование отбора и задаем параметры сравнения
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = ЭлементыФормы.СправочникСписок.ТекущиеДанные.Ссылка;

// 5. Принудительно вызываем обновление (формирование) отчета с нашими новыми параметрами
ФормаОтчета.ОбновитьОтчет();

При таком подходе мы гарантируем, что никакие внутренние механизмы формы не перезапишут наш отбор, так как мы устанавливаем его непосредственно перед выполнением метода ОбновитьОтчет(), когда форма уже полностью готова к работе.

Рекомендации для разработчиков на управляемых формах (СКД)

Если вы работаете в современной конфигурации на платформе 1С:Предприятие 8.3 с использованием управляемых форм и Системы компоновки данных (СКД), то ручное манипулирование объектами отчетов и их формами считается устаревшим подходом.

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


// 1. Формируем структуру отбора
СтруктураОтбора = Новый Структура;
СтруктураОтбора.Вставить("Контрагент", СсылкаНаКонтрагента);

// 2. Заполняем параметры формы, указывая отбор и признак автоформирования
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Отбор", СтруктураОтбора);
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);

// 3. Открываем форму отчета с готовыми параметрами
ОткрытьФорму("Отчет.ПрайсЛистПоКонтрагенту.Форма", ПараметрыФормы);

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

← На главную