Как настроить отбор при выборе элементов справочника в 1С 8.3?

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При разработке документов и справочников в 1С часто возникает задача ограничить список доступных для выбора элементов. Например, в документе есть поле Водитель с типом СправочникСсылка.РабочийПерсонал. Однако в справочнике хранятся сотрудники различных должностей: и водители, и грузчики, и механики. Наша цель — сделать так, чтобы при открытии списка выбора пользователю отображались только сотрудники с должностью «Водитель».

Рассмотрим, почему частые попытки решить эту задачу через событие НачалоВыбора и вызов метода ОткрытьМодально() приводят к ошибкам, и проанализируем наиболее эффективные и правильные способы реализации такой фильтрации.

Типичные ошибки при реализации отбора вручную

Часто разработчики пытаются перехватить событие элемента формы НачалоВыбора, отключить стандартную обработку и вручную открыть форму с наложением отбора на динамический список:


&НаКлиенте
Процедура ВодительНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ФормаВыбора = ПолучитьФорму("Справочник.РабочийПерсонал.ФормаВыбора");    
    ФормаВыбора.Список.Отбор.Элементы.Очистить();
    
    // Настройка отбора по должности
    ЭлементОтбора = ФормаВыбора.Список.Отбор.Элементы.Добавить(Тип("ЭлементОтбораКомпоновкиДанных"));
    ЭлементОтбора.ЛевоеЗначение = Новый ПолеКомпоновкиДанных("Должность"); 
    ЭлементОтбора.ВидСравнения = ВидСравненияКомпоновкиДанных.Равно; 
    ЭлементОтбора.Использование = Истина;
    ЭлементОтбора.ПравоеЗначение = ПредопределенноеЗначение("Перечисление.Должности.Водитель");
    
    ВыбранноеЗначение = ФормаВыбора.ОткрытьМодально();
    Если ЗначениеЗаполнено(ВыбранноеЗначение) Тогда
        Объект.Водитель = ВыбранноеЗначение;
    КонецЕсли;
КонецПроцедуры

Разберем, с какими проблемами можно столкнуться при использовании такого подхода:

  1. Использование модальных вызовов: Метод ОткрытьМодально() считается устаревшим и блокируется в современных конфигурациях при включенном режиме запрета модальных вызовов, а также не работает в веб-клиенте.
  2. Отключение ввод по строке: Установка СтандартнаяОбработка = Ложь отключает платформенный механизм автоподбора при вводе текста в поле.
  3. Сложность поддержки: Код становится громоздким и требует ручного управления передачей и возвратом выбранного значения.

Способ 1. Использование параметров выбора (ПараметрыВыбора)

Самый простой и правильный способ ограничить список выбора в управляемых формах — использовать штатный механизм ПараметрыВыбора. Настроить его можно как в конфигураторе, так и программно.

Вариант А: Настройка в конфигураторе

  1. Откроем свойства нужного реквизита или элемента формы.
  2. Найдем свойство Параметры выбора (ChoiceParameters) и нажмем кнопку открытия.
  3. Добавим новый параметр отбора. В поле «Имя» укажем Отбор.Должность, а в качестве значения выберем Перечисление.Должности.Водитель.

Вариант Б: Программная установка на сервере

Если отбор необходимо сформировать динамически в коде формы, установим параметры выбора в обработчике ПриСозданииНаСервере:


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    МассивПараметров = Новый Массив;
    МассивПараметров.Добавить(Новый ПараметрВыбора("Отбор.Должность", Перечисления.Должности.Водитель));
    
    Элементы.Водитель.ПараметрыВыбора = Новый ФиксированныйМассив(МассивПараметров);
КонецПроцедуры

Этот метод автоматически обеспечивает фильтрацию элементов и в открываемой форме выбора, и при вводе текста с клавиатуры (автоподбор).

Способ 2. Использование связи параметров выбора (СвязиПараметровВыбора)

Если условие фильтрации зависит от значения другого реквизита на форме (например, отбор сотрудников зависит от выбранного подразделения), оптимально использовать механизм СвязиПараметровВыбора.

Настройка выполняется в свойствах элемента формы:

  1. В свойствах поля Водитель находим пункт Связи параметров выбора.
  2. Добавляем связь: указываем имя элемента-источника (например, реквизит Подразделение) и имя реквизита отбора (Отбор.Подразделение).

При изменении подразделения на форме платформа автоматически пересчитает отбор для поля выбора водителя без написания дополнительного кода.

Способ 3. Асинхронное открытие формы выбора (ОткрытьФорму)

Если стандартного механизма параметров выбора недостаточно и требуется сложная логика открытия формы, используем метод ОткрытьФорму с передачей параметров и владельца.


&НаКлиенте
Процедура ВодительНачалоВыбора(Элемент, ДанныеВыбора, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    
    СтруктураОтбора = Новый Структура;
    СтруктураОтбора.Вставить("Должность", ПредопределенноеЗначение("Перечисление.Должности.Водитель"));
    
    ПараметрыФормы = Новый Структура;
    ПараметрыФормы.Вставить("Отбор", СтруктураОтбора);
    
    // Владельцем формы указываем сам элемент формы, чтобы выбранное значение подставилось автоматически
    ОткрытьФорму("Справочник.РабочийПерсонал.ФормаВыбора", ПараметрыФормы, Элемент);
КонецПроцедуры

Передача аргумента Элемент в качестве владельца формы сообщает платформе, куда именно необходимо вернуть результат выбора, исключая необходимость использования модальных окон или ручной обработки события закрытия.

Способ 4. Выбор из строго ограниченного выпадающего списка

Если количество элементов для выбора не велико и нужно отображать их исключительно в виде выпадающего списка без открытия отдельной формы справочника:

  1. В свойствах элемента формы устанавливаем свойство РежимВыбораИзСписка в значение Истина.
  2. Заполняем коллекцию СписокВыбора нужными ссылками на сервере:

&НаСервере
Процедура ЗаполнитьСписокВыбораВодителей()
    Элементы.Водитель.СписокВыбора.Очистить();
    
    Запрос = Новый Запрос;
    Запрос.Текст = 
        "ВЫБРАТЬ
        |	РабочийПерсонал.Ссылка КАК Ссылка
        |ИЗ
        |	Справочник.РабочийПерсонал КАК РабочийПерсонал
        |ГДЕ
        |	РабочийПерсонал.Должность = &Должность";
    
    Запрос.УстановитьПараметр("Должность", Перечисления.Должности.Водитель);
    РезультатЗапроса = Запрос.Выполнить().Выбрать();
    
    Пока РезультатЗапроса.Следующий() Цикл
        Элементы.Водитель.СписокВыбора.Добавить(РезультатЗапроса.Ссылка);
    КонецЦикла;
КонецПроцедуры

Резюме

Для корректного отбора элементов при выборе в 1С 8.3 рекомендуется избегать модальных вызовов и ручного управления формами. В большинстве случаев достаточно установить свойство ПараметрыВыбора или воспользоваться функционалом СвязиПараметровВыбора. Это гарантирует правильную работу интерфейса как в тонком клиенте, так и при использовании веб-клиента.

← На главную