При разработке связанных отчетов на схеме компоновки данных (СКД) часто возникает задача открыть второй отчет с отбором по выбранному значению из первого отчета — например, расшифровать задолженность по конкретному контрагенту. Типовой программный код для решения этой задачи обычно выглядит следующим образом:
Парам = Новый Структура();
Парам.Вставить("СформироватьПриОткрытии", Истина);
Парам.Вставить("Отбор", Новый Структура("Контрагент", СтруктураДанных.Значение));
ОткрытьФорму("Отчет.ДвиженияПоКонтрагенту.Форма.ФормаОтчета", Парам);
Разработчик ожидает увидеть открывшуюся форму с заполненным полем отбора в шапке или на панели быстрых настроек. Однако визуально панель отборов остается пустой. Разберем по шагам, почему так происходит, как на самом деле работает платформа 1С:Предприятие 8 в этом сценарии и какими способами можно вывести отбор на форму.
Проанализируем поведение платформы. Если проверить сформированный отчет, выяснится, что результат уже отфильтрован по нужному контрагенту. То есть переданный отбор действительно сработал. Причина отсутствия элемента на форме кроется в архитектуре разделения настроек в СКД:
Отбор платформа применяет условия напрямую в основные настройки компоновщика: КомпоновщикНастроек.Настройки.Отбор.КомпоновщикНастроек.ПользовательскиеНастройки.Отбор, если поле изначально не было включено в состав пользовательских настроек в схеме СКД.Таким образом, условие фильтрации применяется к выборке данных «за кулисами», но пользователь не видит его в элементах управления на форме отчета.
Использование параметра Отбор при вызове ОткрытьФорму — это базовый механизм, имеющий важные технические ограничения:
ВидСравненияКомпоновкиДанных.Равно). Передать список значений, диапазон или условие «Не равно» через простую структуру невозможно.Это самый простой и рекомендуемый способ, не требующий сложного программного кода. Выполним следующие действия в открываемом отчете:
Контрагент), выберем вид сравнения Равно, а значение оставим пустым.Теперь платформа заранее знает идентификатор пользовательской настройки для поля Контрагент. При вызове ОткрытьФорму с параметром Отбор платформа автоматически найдет существующую пользовательскую настройку, активирует ее флажком и заполнит переданным значением. Поле сразу появится в видимой части формы.
Если требуется передать отбор динамически без предварительного редактирования схемы СКД, воспользуемся стандартным параметром формы ПользовательскиеНастройки. Рассмотрим пример вызова:
ОтчетОбъект = Отчеты.ДвиженияПоКонтрагенту.Создать();
Компоновщик = ОтчетОбъект.КомпоновщикНастроек;
ЭлементОтбора = Компоновщик.Настройки.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент");
ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно;
ЭлементОтбора.ПравоеЗначение = СтруктураДанных.Значение;
ЭлементОтбора.Использование = Истина;
ЭлементОтбора.ИдентификаторПользовательскойНастройки = Новый УникальныйИдентификатор();
Компоновщик.ПользовательскиеНастройки.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
ЗаполнитьЗначенияСвойств(Компоновщик.ПользовательскиеНастройки.Элементы[Компоновщик.ПользовательскиеНастройки.Элементы.Количество() - 1], ЭлементОтбора);
ПараметрыФормы = Новый Структура();
ПараметрыФормы.Вставить("СформироватьПриОткрытии", Истина);
ПараметрыФормы.Вставить("ПользовательскиеНастройки", Компоновщик.ПользовательскиеНастройки);
ОткрытьФорму("Отчет.ДвиженияПоКонтрагенту.Форма.ФормаОтчета", ПараметрыФормы);
В этом сценарии мы явно связали элемент отбора через свойство ИдентификаторПользовательскойНастройки и передали готовый объект типа ПользовательскиеНастройкиКомпоновкиДанных в форму отчета.
Если у открываемого отчета есть собственная управляемая форма, разберем перехват параметров непосредственно внутри модуля формы. Это дает максимальную гибкость управления настройками:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("ОтборКонтрагент") Тогда
НайденныйЭлемент = Неопределено;
Для Каждого Элемент Из Отчет.КомпоновщикНастроек.ПользовательскиеНастройки.Элементы Цикл
Если ТипЗнч(Элемент) = Тип("ЭлементОтбораКомпоновкиДанных") И Элемент.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Контрагент") Тогда
НайденныйЭлемент = Элемент;
Прервать;
КонецЕсли;
КонецЦикла;
Если НайденныйЭлемент <> Неопределено Тогда
НайденныйЭлемент.Использование = Истина;
НайденныйЭлемент.ПравоеЗначение = Параметры.ОтборКонтрагент;
КонецЕсли;
КонецЕсли;
КонецПроцедуры
При таком подходе в вызывающем коде достаточно передать свой произвольный параметр: Парам.Вставить("ОтборКонтрагент", СтруктураДанных.Значение), а форма отчета сама корректно применит его и к логике отчета, и к пользовательскому интерфейсу.
Если второй отчет открывается по двойному клику на ячейку отчета-источника (поле контрагента), наиболее надежным и штатным решением платформы является использование стандартного механизма расшифровок:
ОбработкаРасшифровки.ОбработкаРасшифровкиКомпоновкиДанных, инициализируя его данными расшифровки исходного отчета.Штатный механизм расшифровки компоновки данных самостоятельно сопоставляет поля группировок первого отчета с доступными полями отбора второго отчета, корректно заполняет пользовательские настройки и обеспечивает прозрачное отображение фильтров для пользователя.