При поддержке старых отчетов и обработок на обычных (неуправляемых) формах разработчики нередко сталкиваются с ситуацией, когда отчет формируется сложным программным кодом («пешком») без использования СКД или построителя отчетов, но пользователям требуется удобный типовой интерфейс быстрого отбора — с возможностью выбора видов сравнения (Равно, В списке, В группе, Не равно и др.) и подбором значений.
Разберем подробно, как реализовать типовой отбор в обычном отчете с минимальными доработками, не переписывая базовый алгоритм формирования отчета.
В типовых конфигурациях на платформе 1С:Предприятие 8 (таких как «Управление торговлей 10.3», «Управление производственным предприятием 1.3», «Комплексная автоматизация 1.1») интерфейс быстрых отборов опирается на объект ПостроительОтчета или ПостроительЗапроса и сервисные процедуры общего модуля УправлениеОтчетами.
Для каждого поля отбора на форме обычно размещается три элемента управления:
Флажок) — определяет, включен ли отбор.ПолеВыбора) — список доступных вариантов (Равно, ВСписке, ВИерархии и т. д.).ПолеВвода) — принимает конкретную ссылку, примитивное значение или СписокЗначений в зависимости от выбранного вида сравнения.Процедуры модуля УправлениеОтчетами автоматически переключают тип поля ввода (со ссылки на список и обратно) при смене вида сравнения и синхронизируют значения с коллекцией отбора построителя.
Рассмотрим, как инициализировать объект ПостроительОтчета и связать его с элементами формы при открытии отчета или в модуле объекта.
Шаг 1. Инициализация фиктивного запроса с описанием полей отбора
Чтобы ПостроительОтчета сформировал корректные метаданные для фильтрации, передадим ему фиктивный текст запроса, содержащий конструкции {ГДЕ ...} для всех необходимых полей:
Текст =
"ВЫБРАТЬ
| Номенклатура.Ссылка КАК Номенклатура,
| NULL КАК Склад
|ИЗ
| Справочник.Номенклатура КАК Номенклатура
|{ГДЕ
| Номенклатура.Ссылка КАК Номенклатура}
|
|ОБЪЕДИНИТЬ ВСЕ
|
|ВЫБРАТЬ
| NULL,
| Склады.Ссылка
|ИЗ
| Справочник.Склады КАК Склады
|{ГДЕ
| Склады.Ссылка КАК Склады}";
ПостроительОтчета.Текст = Текст;
ПостроительОтчета.ЗаполнитьНастройки();
Шаг 2. Настройка доступных полей отбора
Очистим коллекцию отборов и добавим только те реквизиты, которые требуются для быстрого выбора на форме:
ПостроительОтчета.Отбор.Очистить();
ПостроительОтчета.Отбор.Добавить("Номенклатура");
ПостроительОтчета.Отбор.Добавить("Склады");
Шаг 3. Связывание элементов формы с коллекцией отбора
Вызовем типовую процедуру привязки полей ввода к свойствам отбора. В обработчике формы (например, ПриОткрытии или специальной процедуре инициализации) выполним следующий вызов:
УправлениеОтчетами.УстановитьСвязьПолейБыстрогоОтбораНаФорме(
ЭлементыФормы,
ПостроительОтчета.Отбор,
СтруктураСвязиЭлементовСДанными,
"ОтчетОбъект.ПостроительОтчета.Отбор"
);
// При необходимости можно вручную расширить список доступных видов сравнения:
ЭлементыФормы.ПолеВидаСравненияНоменклатура.СписокВыбора.Добавить(ВидСравнения.НеСодержит);
Шаг 4. Обработка событий изменения полей на форме
Для всех элементов управления значениями отбора назначим типовой обработчик изменения:
Процедура ПолеНастройкиПриИзменении(Элемент)
УправлениеОтчетами.ПолеНастройкиПриИзменении(Элемент, ПостроительОтчета.Отбор);
КонецПроцедуры
Когда пользователь настроит фильтр на форме, значения будут записаны в коллекцию ПостроительОтчета.Отбор. Разберем два варианта дальнейшего использования этих данных в алгоритме формирования.
Вариант 1. Получение готового запроса через ПостроительЗапроса / ПостроительОтчета
Если в коде выполняется один основной запрос, наиболее надежным решением является генерация текста запроса средствами самого построителя. При вызове метода ПостроительОтчета.ПолучитьЗапрос() платформа автоматически подставит в запрос все условия (с учетом В ИЕРАРХИИ, В СПИСКЕ и т. д.) и заполнит параметры.
Вариант 2. Ручной разбор коллекции отбора
Если данные собираются в цикле, по сложным условиям или из нескольких не связанных между собой источников, прочитаем состояние элементов отбора программно:
ЭлементОтбора = ПостроительОтчета.Отбор.Найти("Номенклатура");
Если ЭлементОтбора <> Неопределено И ЭлементОтбора.Использование Тогда
ВидСравненияОтбора = ЭлементОтбора.ВидСравнения;
ЗначениеОтбора = ЭлементОтбора.Значение;
// Передаем параметры в запрос или модуль выгрузки
Запрос.УстановитьПараметр("НоменклатураОтбор", ЗначениеОтбора);
КонецЕсли;
Важный нюанс: при ручной подстановке условий в текст запроса учитывайте, что если пользователь выбрал вид сравнения ВидСравнения.ВИерархии или ВидСравнения.ВСпискеПоИерархии, в запросе 1С обязательно должна использоваться синтаксическая конструкция В ИЕРАРХИИ (&Параметр), иначе выборка по группам справочника не сработает.
Если нет необходимости размещать отдельные поля отбора непосредственно в шапке формы, можно разместить на форме элемент управления Табличное поле и установить его свойство ТипЗначения в Отбор (или связать его свойство Данные с ПостроительОтчета.Отбор). В этом случае платформа 1С автоматически предоставит стандартную таблицу настройки фильтрации со всеми доступными полями, типами сравнений и подбором списков без дополнительного программного кода.