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