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