Как открыть форму отчета СКД с отбором и отобразить его в настройках на форме?

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

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


Парам = Новый Структура();
Парам.Вставить("СформироватьПриОткрытии", Истина);
Парам.Вставить("Отбор", Новый Структура("Контрагент", СтруктураДанных.Значение));
ОткрытьФорму("Отчет.ДвиженияПоКонтрагенту.Форма.ФормаОтчета", Парам);

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

Почему отчет формируется с отбором, но поле не отображается на форме

Проанализируем поведение платформы. Если проверить сформированный отчет, выяснится, что результат уже отфильтрован по нужному контрагенту. То есть переданный отбор действительно сработал. Причина отсутствия элемента на форме кроется в архитектуре разделения настроек в СКД:

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

Таким образом, условие фильтрации применяется к выборке данных «за кулисами», но пользователь не видит его в элементах управления на форме отчета.

Ограничения стандартного параметра «Отбор»

Использование параметра Отбор при вызове ОткрытьФорму — это базовый механизм, имеющий важные технические ограничения:

  1. Поддерживается только прямое равенство (ВидСравненияКомпоновкиДанных.Равно). Передать список значений, диапазон или условие «Не равно» через простую структуру невозможно.
  2. Отбор действует только в рамках текущего открытого сеанса формы и не сохраняется в пользовательских вариантах отчета.
  3. Если пользователь нажмет кнопку сброса или переформирования без учета основных настроек, отбор может быть потерян.

Способ 1. Включение отбора в пользовательские настройки в схеме СКД

Это самый простой и рекомендуемый способ, не требующий сложного программного кода. Выполним следующие действия в открываемом отчете:

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

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

Способ 2. Программное заполнение пользовательских настроек через параметры

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


ОтчетОбъект = Отчеты.ДвиженияПоКонтрагенту.Создать();
Компоновщик = ОтчетОбъект.КомпоновщикНастроек;

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

Компоновщик.ПользовательскиеНастройки.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(Компоновщик.ПользовательскиеНастройки.Элементы[Компоновщик.ПользовательскиеНастройки.Элементы.Количество() - 1], ЭлементОтбора);

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

ОткрытьФорму("Отчет.ДвиженияПоКонтрагенту.Форма.ФормаОтчета", ПараметрыФормы);

В этом сценарии мы явно связали элемент отбора через свойство ИдентификаторПользовательскойНастройки и передали готовый объект типа ПользовательскиеНастройкиКомпоновкиДанных в форму отчета.

Способ 3. Обработка параметров в событии формы «ПриСозданииНаСервере»

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    
    Если Параметры.Свойство("ОтборКонтрагент") Тогда
        
        НайденныйЭлемент = Неопределено;
        Для Каждого Элемент Из Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
            Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") И Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент") Тогда
                НайденныйЭлемент = Элемент;
                Прервать;
            КонецЕсли;
        КонецЦикла;
        
        Если НайденныйЭлемент <> Неопределено Тогда
            НайденныйЭлемент.Использование = Истина;
            НайденныйЭлемент.ПравоеЗначение = Параметры.ОтборКонтрагент;
        КонецЕсли;
        
    КонецЕсли;
    
КонецПроцедуры

При таком подходе в вызывающем коде достаточно передать свой произвольный параметр: Парам.Вставить("ОтборКонтрагент", СтруктураДанных.Значение), а форма отчета сама корректно применит его и к логике отчета, и к пользовательскому интерфейсу.

Способ 4. Использование штатного механизма расшифровки СКД

Если второй отчет открывается по двойному клику на ячейку отчета-источника (поле контрагента), наиболее надежным и штатным решением платформы является использование стандартного механизма расшифровок:

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

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

← На главную