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