К статье
Практический материал

Разработка и Конфигурация · 12 мин

Как открыть форму выбора с отбором в обычных формах 1С

Как открыть форму выбора с отбором в обычных формах 1С 8.2/8.3: ПолучитьФорму, ОткрытьФормуМодально, установка отбора, примеры кода и типичные ошибки.

В обычных формах 1С (платформа 8.2/8.3, режим обычного приложения) открытие формы выбора с предустановленным отбором — типовая задача: пользователь должен подобрать, например, только номенклатуру из конкретной группы или контрагентов с определённым признаком. В отличие от управляемых форм, где используются параметры формы и структура отбора, в обычных формах фильтр устанавливается через объект формы после её получения.

Ключевой механизм — функция ПолучитьФорму() или метод ПолучитьФормуВыбора(), которые возвращают объект формы. У этого объекта доступны свойства списка: Отбор, Порядок, Настройки. Отбор задаётся до вызова Открыть() или ОткрытьМодально(), иначе пользователь увидит нефильтрованный список.

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

Как работает отбор в обычных формах выбора

Форма выбора справочника или документа в обычном приложении содержит табличное поле, связанное с объектом списка — СправочникСписок, ДокументСписок и т.д. У этого объекта есть свойство Отбор — коллекция элементов отбора, аналогичная отбору динамического списка, но управляемая программно напрямую.

Каждый элемент отбора имеет свойства: Имя (путь к полю), ВидСравнения (равно, в списке, в иерархии и др.), Значение и Использование. Если Использование не установить в Истина, элемент будет существовать, но фильтр не применится — это самая частая причина «неработающего» отбора.

Отбор применяется к списку в момент открытия формы. Если форма уже открыта и вы меняете отбор, список обновится автоматически. Но если форма открывается впервые, правильный порядок: получить объект формы → настроить отбор → открыть форму пользователю.

Базовый пример: открыть выбор с отбором по реквизиту

Задача: из поля ввода открыть выбор номенклатуры, показывая только элементы с признаком услуги. Используем обработчик НачалоВыбора поля ввода.

Процедура НоменклатураНачалоВыбора(Элемент, СтандартнаяОбработка)

СтандартнаяОбработка = Ложь;

ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);

ЭлементОтбора = ФормаВыбора.Отбор.Элементы.Добавить();

ЭлементОтбора.Имя = "Услуга";

ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;

ЭлементОтбора.Значение = Истина;

ЭлементОтбора.Использование = Истина;

ФормаВыбора.ОткрытьМодально();

КонецПроцедуры

Второй параметр ПолучитьФормуВыбора(, Элемент) задаёт владельца формы — поле ввода. Благодаря этому после выбора значение автоматически попадёт в поле, и сработают стандартные обработчики ОбработкаВыбора. Если владельца не указать, результат выбора придётся обрабатывать вручную.

Обратите внимание: СтандартнаяОбработка = Ложь обязательна, иначе после вашего кода откроется ещё и стандартная форма выбора без отбора.

bsl
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);
ЭлементОтбора = ФормаВыбора.Отбор.Элементы.Добавить();
ЭлементОтбора.Имя = "Услуга";
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = Истина;
ЭлементОтбора.Использование = Истина;
ФормаВыбора.ОткрытьМодально();

Отбор по нескольким условиям и по списку значений

Несколько условий добавляются последовательно — они объединяются по «И». Например, показать только непомеченных контрагентов из конкретной группы:

ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);

ОтборГруппа = ФормаВыбора.Отбор.Элементы.Добавить();

ОтборГруппа.Имя = "Родитель";

ОтборГруппа.ВидСравнения = ВидСравнения.ВИерархии;

ОтборГруппа.Значение = ГруппаОпт;

ОтборГруппа.Использование = Истина;

ОтборПометка = ФормаВыбора.Отбор.Элементы.Добавить();

ОтборПометка.Имя = "ПометкаУдаления";

ОтборПометка.ВидСравнения = ВидСравнения.Равно;

ОтборПометка.Значение = Ложь;

ОтборПометка.Использование = Истина;

Для отбора по нескольким значениям одного поля используйте вид сравнения ВСписке и передайте СписокЗначений. Это удобно, когда допустимы, например, несколько видов номенклатуры. Вид сравнения ВИерархии работает только для иерархических справочников и включает саму группу и все вложенные элементы.

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

Порядок действий
  1. 1
    Откройте модуль формы и найдите обработчик НачалоВыбора нужного поля ввода
  2. 2
    Установите СтандартнаяОбработка = Ложь
  3. 3
    Получите форму выбора через ПолучитьФормуВыбора() с указанием владельца
  4. 4
    Добавьте элементы отбора, задав Имя, ВидСравнения, Значение и Использование = Истина
  5. 5
    Вызовите ОткрытьМодально() и проверьте, что список отфильтрован и выбор возвращается в поле

Как запретить пользователю снимать отбор

По умолчанию пользователь может открыть настройку отбора в форме списка и отключить ваш фильтр — тогда он увидит и выберет «запрещённые» элементы. Чтобы этого не допустить, у формы выбора предусмотрено свойство РежимОтбора (у объекта формы списка) либо используется свойство элемента отбора РежимОтображения.

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

Дополнительная защита — проверка при записи/проведении на сервере. Даже если интерфейс ограничен, контроль в модуле объекта гарантирует, что в базу не попадёт элемент, нарушающий условие, — например, при обходе через буфер обмена или ввод по строке.

Модальное открытие и получение результата выбора

Если форма выбора открывается не из поля ввода, а из кнопки (например, «Подобрать сотрудника»), владельца-поля нет, и результат нужно получить вручную. Метод ОткрытьМодально() возвращает выбранное значение, если форма выбора стандартная:

ФормаВыбора = Справочники.Сотрудники.ПолучитьФормуВыбора();

// ... установка отбора ...

Результат = ФормаВыбора.ОткрытьМодально();

Если Результат <> Неопределено Тогда

ТекущийСотрудник = Результат;

КонецЕсли;

Альтернатива — назначить форму владельцем текущей формы и перехватить выбор в обработчике ОбработкаВыбора(ЗначениеВыбора, Источник) формы-владельца. Этот вариант предпочтительнее, когда нужно отличать выбор из разных кнопок: проверяйте параметр Источник.

Учтите ограничение: модальное открытие блокирует родительское окно. В режиме обычного приложения это допустимо и широко используется, но если конфигурация планирует переход на управляемые формы или веб-клиент, модальные вызовы придётся переписывать на ОткрытьФорму с описанием оповещения.

Сравнение вариантов

ОткрытьМодально()

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

Владелец формы + ОбработкаВыбора

Значение приходит в обработчик формы-владельца. Гибче при нескольких источниках выбора, но требует дополнительного обработчика.

Поле ввода как владелец

Стандартное поведение подбора: значение само попадает в поле. Минимум кода, но подходит только для выбора в конкретное поле.

Ключ уникальности и повторное открытие формы

Функция ПолучитьФорму() и ПолучитьФормуВыбора() принимают параметр «КлючУникальности». Если вызывать получение формы без ключа дважды, платформа вернёт один и тот же уже открытый экземпляр — и ваш новый отбор может примениться к форме, которую пользователь уже использует с другими настройками, либо, наоборот, старый отбор «переживёт» новый вызов.

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

ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент, Новый УникальныйИдентификатор);

Перед установкой нового отбора в переиспользуемой форме очищайте коллекцию: ФормаВыбора.Отбор.Элементы.Очистить(). Иначе элементы отбора будут накапливаться, и условия станут противоречивыми — список окажется пустым без видимой причины.

Типичные ошибки
01
Не установлено Использование = Истина — элемент отбора существует, но фильтр не применяется, список показывает всё подряд
02
Отбор устанавливается после ОткрытьМодально() — форма уже показана без фильтра, изменения видны только при следующем открытии
03
Не очищена коллекция Элементы при повторном использовании формы — условия накапливаются, список становится пустым
04
Забыто СтандартнаяОбработка = Ложь — открываются две формы: ваша с отбором и стандартная без него
05
Отбор по несуществующему имени поля — ошибка выполнения при открытии формы

Проверка результата и ограничения подхода

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

Для ограничения быстрого ввода в обычных формах используйте свойство поля ввода «Параметры выбора» или обработчик АвтоПодборТекста, иначе пользователь введёт наименование «запрещённого» элемента вручную, минуя форму выбора.

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

Контрольные точки

Как проверить результат

Содержимое списка при открытии
Норма

Видны только элементы, удовлетворяющие условию

Тревожный признак

Список полный — проверьте Использование и имя поля отбора

Возврат значения
Норма

После двойного клика значение появляется в поле ввода

Тревожный признак

Ничего не происходит — не задан владелец формы

Повторное открытие
Норма

Отбор соответствует текущему вызову

Тревожный признак

Остались условия прошлого вызова — очищайте Элементы

Быстрый ввод с клавиатуры
Норма

Подбираются только разрешённые элементы

Тревожный признак

Находится любой элемент — настройте параметры выбора поля

Часто задаваемые вопросы

Чем отличается ПолучитьФорму() от ПолучитьФормуВыбора()?

ПолучитьФорму() открывает произвольную форму объекта по имени, а ПолучитьФормуВыбора() возвращает именно форму выбора, назначенную объекту в конфигураторе. Для задачи «открыть выбор с отбором» корректнее использовать ПолучитьФормуВыбора() — тогда учитывается переопределённая форма выбора конфигурации.

Почему отбор не применяется, хотя код выполняется без ошибок?

Чаще всего не установлено свойство Использование = Истина у элемента отбора либо отбор задаётся после вызова ОткрытьМодально(). Реже — имя поля указано с ошибкой или отбор очищается кодом самой формы при её создании.

Можно ли открыть форму выбора с отбором в управляемом приложении тем же кодом?

Нет. В управляемых формах используется ОткрытьФорму() с параметром «Отбор» — структурой, где ключи это имена полей. Механизм ПолучитьФормуВыбора и объект Отбор формы списка относится только к обычным формам.

Как передать в форму выбора сложное условие, которое не выразить элементом отбора?

Добавьте в форму выбора собственный реквизит-параметр, при создании формы примите значение и в обработчике ПриОткрытии установите произвольный отбор или измените запрос списка. Альтернатива для обычных форм — использовать свойство ПроизвольныйЗапрос у объекта списка с готовым текстом запроса.

Пользователь снимает отбор через кнопку настройки списка. Что делать?

Скройте или отключите кнопки отбора на командной панели табличного поля формы выбора и дублируйте критичные ограничения проверкой в модуле объекта. Интерфейсный отбор сам по себе не является надёжным ограничением.

Итог

Что важно запомнить

Отбор в обычных формах выбора задаётся через объект формы: ПолучитьФормуВыбора → добавление элементов отбора с Использование = Истина → ОткрытьМодально(). Очищайте коллекцию отбора при повторном использовании формы, ограничивайте возможность снять фильтр и дублируйте критичные ограничения проверками на уровне данных.