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