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