Как правильно настроить отбор в форме выбора справочника в 1С 8.3: программные и декларативные методы

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

В процессе разработки бизнес-приложений на платформе 1С:Предприятие часто возникает классическая задача: при выборе значения в поле ввода ограничить список выбора по определенным критериям. Наиболее частый пример — выбор договора контрагента. Нам необходимо, чтобы в форме выбора отображались только договоры конкретного контрагента (владельца) и только определенного вида (например, «Договор поручительства»).

Разберем детально, почему стандартные попытки написать такой отбор «в лоб» часто не работают, проанализируем типичные ошибки разработчиков и рассмотрим несколько надежных способов реализации этой задачи: от декларативной настройки в конфигураторе до продвинутых программных методов.

Анализ типичных ошибок при программном открытии формы

Рассмотрим код, который часто пытаются использовать начинающие разработчики:


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

В этом небольшом фрагменте кода скрыто сразу три критические ошибки:

  1. Неверная структура параметров открытия. Передача произвольного параметра напрямую в структуру ПараметрыОткрытия не заставит динамический список формы выбора автоматически отфильтровать данные. Платформа ожидает увидеть строго определенный параметр с именем Отбор, значением которого должна являться вложенная структура.
  2. Путаница в именах полей. В качестве ключа отбора передается имя реквизита текущего объекта или формы (Лк_ДоговорПоручителя), в то время как отбор должен накладываться на реквизиты выбираемого справочника (например, Владелец или ВидДоговора).
  3. Неверный владелец формы выбора. Третьим параметром в функцию ОткрытьФорму передается контекст текущей формы (ЭтотОбъект). Из-за этого платформа не понимает, в какое именно поле ввода нужно вернуть выбранное значение. Разработчику придется вручную описывать событие ОбработкаВыбора, хотя при передаче самого элемента управления (переменная Элемент) подстановка произошла бы автоматически.

Давайте подробно рассмотрим правильные варианты реализации этой задачи.

Способ 1. Декларативная настройка в конфигураторе (No-Code)

Прежде чем писать программный код, выясним, можно ли решить задачу стандартными интерактивными средствами платформы 1С. В подавляющем большинстве случаев для связи справочников «Контрагенты» и «Договоры» писать код вообще не требуется.

Выполним настройку в конфигураторе:

  1. Откроем свойства реквизита Договор (в документе или справочнике, где осуществляется выбор).
  2. Найдем свойство Связи параметров выбора и нажмем кнопку открытия. Добавим новую строку:
    • Имя параметра строки: Выберем Отбор.Владелец.
    • Поле выбора: Укажем реквизит нашей формы Объект.Контрагент.
    • Режим очистки: Установим значение «Очищать» (при изменении контрагента ранее выбранный договор автоматически сотрется).
  3. Найдем свойство Параметры выбора. Добавим ограничение по виду договора:
    • Имя параметра: Отбор.ВидДоговора.
    • Значение: Выберем соответствующее значение из перечисления (например, ПредопределенноеЗначение("Перечисление.ВидыДоговоров.Поручительство") или конкретное значение типа).

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

Способ 2. Программная динамическая настройка параметров выбора

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

Разберем этот элегантный метод на примере обработчика НачалоВыбора:


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

Преимущества метода: Сохраняется вся стандартная эргономика поля ввода. Работает автоматический подбор при вводе текста с клавиатуры (ввод по строке), выпадающие списки быстрого выбора и кнопка создания нового элемента прямо из формы списка.

Способ 3. Программное открытие формы через структуру «Отбор»

Если нам всё же требуется полностью переопределить логику открытия формы выбора, мы должны использовать правильную структуру параметров. Посмотрим на корректную реализацию метода с использованием стандартного параметра расширения управляемой формы Отбор:


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

В этом коде критически важно передавать в качестве владельца именно переменную Элемент. В этом случае после выбора договора в открывшемся списке платформа автоматически поместит его в наше поле ввода без дополнительного кодирования.

Способ 4. Надежный отбор через «ФиксированныеНастройки»

Использование параметра Отбор имеет один существенный недостаток: пользователь может зайти в настройки открывшейся формы выбора списка (через «Еще - Настроить список») и вручную отключить или изменить установленный нами отбор. Кроме того, простой Отбор поддерживает исключительно сравнение на равенство.

Чтобы установить жесткий и сложный фильтр, который пользователь гарантированно не сможет сбросить, применим механизм компоновки данных и параметр ФиксированныеНастройки:


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

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

Важная особенность: автозаполнение при создании

Если мы используем штатные механизмы фильтрации (способы 1, 2, 3 и 4), платформа автоматически транслирует установленные отборы при создании нового элемента. Находясь в отфильтрованной форме выбора договоров, при нажатии кнопки Создать в открывшейся форме нового договора поле Владелец (Контрагент) уже будет заполнено нужным контрагентом автоматически.

Если же мы решим делать отбор кустарно (например, подменяя текст произвольного запроса динамического списка), автозаполнение при создании нового элемента работать перестанет, что доставит крайнее неудобство конечным пользователям системы.

← На главную