Разработка и Конфигурация · 12 мин
Как открыть форму выбора с отбором в обычных формах 1С
Как открыть форму выбора с отбором в обычных формах 1С 8.2/8.3: ПолучитьФорму, ОткрытьФормуМодально, установка отбора, примеры кода и типичные ошибки.
В обычных формах 1С (платформа 8.2/8.3, режим обычного приложения) открытие формы выбора с предустановленным отбором — типовая задача: пользователь должен подобрать, например, только номенклатуру из конкретной группы или контрагентов с определённым признаком. В отличие от управляемых форм, где используются параметры формы и структура отбора, в обычных формах фильтр устанавливается через объект формы после её получения.
Ключевой механизм — функция ПолучитьФорму() или метод ПолучитьФормуВыбора(), которые возвращают объект формы. У этого объекта доступны свойства списка: Отбор, Порядок, Настройки. Отбор задаётся до вызова Открыть() или ОткрытьМодально(), иначе пользователь увидит нефильтрованный список.
Ниже разобраны рабочие способы: установка отбора через объект формы, работа с ключом уникальности, модальное открытие для получения результата выбора, запрет изменения отбора пользователем и типичные ошибки, из-за которых фильтр «слетает» или форма открывается без ограничений.
Как работает отбор в обычных формах выбора
Форма выбора справочника или документа в обычном приложении содержит табличное поле, связанное с объектом списка — СправочникСписок, ДокументСписок и т.д. У этого объекта есть свойство Отбор — коллекция элементов отбора, аналогичная отбору динамического списка, но управляемая программно напрямую.
Каждый элемент отбора имеет свойства: Имя (путь к полю), ВидСравнения (равно, в списке, в иерархии и др.), Значение и Использование. Если Использование не установить в Истина, элемент будет существовать, но фильтр не применится — это самая частая причина «неработающего» отбора.
Отбор применяется к списку в момент открытия формы. Если форма уже открыта и вы меняете отбор, список обновится автоматически. Но если форма открывается впервые, правильный порядок: получить объект формы → настроить отбор → открыть форму пользователю.
Базовый пример: открыть выбор с отбором по реквизиту
Задача: из поля ввода открыть выбор номенклатуры, показывая только элементы с признаком услуги. Используем обработчик НачалоВыбора поля ввода.
Процедура НоменклатураНачалоВыбора(Элемент, СтандартнаяОбработка)
СтандартнаяОбработка = Ложь;
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);
ЭлементОтбора = ФормаВыбора.Отбор.Элементы.Добавить();
ЭлементОтбора.Имя = "Услуга";
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = Истина;
ЭлементОтбора.Использование = Истина;
ФормаВыбора.ОткрытьМодально();
КонецПроцедуры
Второй параметр ПолучитьФормуВыбора(, Элемент) задаёт владельца формы — поле ввода. Благодаря этому после выбора значение автоматически попадёт в поле, и сработают стандартные обработчики ОбработкаВыбора. Если владельца не указать, результат выбора придётся обрабатывать вручную.
Обратите внимание: СтандартнаяОбработка = Ложь обязательна, иначе после вашего кода откроется ещё и стандартная форма выбора без отбора.
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент);
ЭлементОтбора = ФормаВыбора.Отбор.Элементы.Добавить();
ЭлементОтбора.Имя = "Услуга";
ЭлементОтбора.ВидСравнения = ВидСравнения.Равно;
ЭлементОтбора.Значение = Истина;
ЭлементОтбора.Использование = Истина;
ФормаВыбора.ОткрытьМодально();Отбор по нескольким условиям и по списку значений
Несколько условий добавляются последовательно — они объединяются по «И». Например, показать только непомеченных контрагентов из конкретной группы:
ФормаВыбора = Справочники.Контрагенты.ПолучитьФормуВыбора(, Элемент);
ОтборГруппа = ФормаВыбора.Отбор.Элементы.Добавить();
ОтборГруппа.Имя = "Родитель";
ОтборГруппа.ВидСравнения = ВидСравнения.ВИерархии;
ОтборГруппа.Значение = ГруппаОпт;
ОтборГруппа.Использование = Истина;
ОтборПометка = ФормаВыбора.Отбор.Элементы.Добавить();
ОтборПометка.Имя = "ПометкаУдаления";
ОтборПометка.ВидСравнения = ВидСравнения.Равно;
ОтборПометка.Значение = Ложь;
ОтборПометка.Использование = Истина;
Для отбора по нескольким значениям одного поля используйте вид сравнения ВСписке и передайте СписокЗначений. Это удобно, когда допустимы, например, несколько видов номенклатуры. Вид сравнения ВИерархии работает только для иерархических справочников и включает саму группу и все вложенные элементы.
Отбор по реквизиту, который не выведен в список формы выбора, работает корректно — платформа фильтрует на уровне объекта списка, а не отображаемых колонок. Однако если форма выбора в конфигурации переопределена и построена на произвольном запросе, стандартный Отбор может отсутствовать или вести себя иначе — проверяйте устройство конкретной формы.
- 1Откройте модуль формы и найдите обработчик НачалоВыбора нужного поля ввода
- 2Установите СтандартнаяОбработка = Ложь
- 3Получите форму выбора через ПолучитьФормуВыбора() с указанием владельца
- 4Добавьте элементы отбора, задав Имя, ВидСравнения, Значение и Использование = Истина
- 5Вызовите ОткрытьМодально() и проверьте, что список отфильтрован и выбор возвращается в поле
Как запретить пользователю снимать отбор
По умолчанию пользователь может открыть настройку отбора в форме списка и отключить ваш фильтр — тогда он увидит и выберет «запрещённые» элементы. Чтобы этого не допустить, у формы выбора предусмотрено свойство РежимОтбора (у объекта формы списка) либо используется свойство элемента отбора РежимОтображения.
Практический способ — установить для элемента отбора РежимОтображения = РежимОтображенияЭлементаНастройкиКомпоновки.Недоступный там, где это поддерживается, либо скрыть у табличного поля командную панель отбора. В типовых обычных формах надёжнее всего комбинация: отбор установлен программно, а у формы отключена кнопка «Отбор» на командной панели списка.
Дополнительная защита — проверка при записи/проведении на сервере. Даже если интерфейс ограничен, контроль в модуле объекта гарантирует, что в базу не попадёт элемент, нарушающий условие, — например, при обходе через буфер обмена или ввод по строке.
Модальное открытие и получение результата выбора
Если форма выбора открывается не из поля ввода, а из кнопки (например, «Подобрать сотрудника»), владельца-поля нет, и результат нужно получить вручную. Метод ОткрытьМодально() возвращает выбранное значение, если форма выбора стандартная:
ФормаВыбора = Справочники.Сотрудники.ПолучитьФормуВыбора();
// ... установка отбора ...
Результат = ФормаВыбора.ОткрытьМодально();
Если Результат <> Неопределено Тогда
ТекущийСотрудник = Результат;
КонецЕсли;
Альтернатива — назначить форму владельцем текущей формы и перехватить выбор в обработчике ОбработкаВыбора(ЗначениеВыбора, Источник) формы-владельца. Этот вариант предпочтительнее, когда нужно отличать выбор из разных кнопок: проверяйте параметр Источник.
Учтите ограничение: модальное открытие блокирует родительское окно. В режиме обычного приложения это допустимо и широко используется, но если конфигурация планирует переход на управляемые формы или веб-клиент, модальные вызовы придётся переписывать на ОткрытьФорму с описанием оповещения.
Сравнение вариантов
Код продолжается после выбора, результат возвращается напрямую. Подходит для обычного приложения, но блокирует интерфейс и не переносится на управляемые формы.
Значение приходит в обработчик формы-владельца. Гибче при нескольких источниках выбора, но требует дополнительного обработчика.
Стандартное поведение подбора: значение само попадает в поле. Минимум кода, но подходит только для выбора в конкретное поле.
Ключ уникальности и повторное открытие формы
Функция ПолучитьФорму() и ПолучитьФормуВыбора() принимают параметр «КлючУникальности». Если вызывать получение формы без ключа дважды, платформа вернёт один и тот же уже открытый экземпляр — и ваш новый отбор может примениться к форме, которую пользователь уже использует с другими настройками, либо, наоборот, старый отбор «переживёт» новый вызов.
Передавайте уникальный ключ, когда из разных мест программы нужны формы выбора с разными отборами одного и того же справочника:
ФормаВыбора = Справочники.Номенклатура.ПолучитьФормуВыбора(, Элемент, Новый УникальныйИдентификатор);
Перед установкой нового отбора в переиспользуемой форме очищайте коллекцию: ФормаВыбора.Отбор.Элементы.Очистить(). Иначе элементы отбора будут накапливаться, и условия станут противоречивыми — список окажется пустым без видимой причины.
Проверка результата и ограничения подхода
После внедрения проверьте три вещи. Во-первых, откройте форму и убедитесь, что список содержит только ожидаемые элементы, а индикатор отбора (если он отображается) показывает ваши условия. Во-вторых, выполните выбор — значение должно попасть в поле ввода или обработчик. В-третьих, попробуйте ввод по строке в поле ввода: стандартный быстрый подбор может игнорировать ваш отбор, если не настроены параметры выбора поля.
Для ограничения быстрого ввода в обычных формах используйте свойство поля ввода «Параметры выбора» или обработчик АвтоПодборТекста, иначе пользователь введёт наименование «запрещённого» элемента вручную, минуя форму выбора.
Помните про границы механизма: программный отбор формы не заменяет права доступа и RLS, не работает как защита при загрузке данных извне, и ломается, если форма выбора в конфигурации заменена на произвольную с собственным запросом. В таких случаях отбор нужно передавать через параметры и применять внутри самой формы.
Как проверить результат
Видны только элементы, удовлетворяющие условию
Список полный — проверьте Использование и имя поля отбора
После двойного клика значение появляется в поле ввода
Ничего не происходит — не задан владелец формы
Отбор соответствует текущему вызову
Остались условия прошлого вызова — очищайте Элементы
Подбираются только разрешённые элементы
Находится любой элемент — настройте параметры выбора поля
Часто задаваемые вопросы
Чем отличается ПолучитьФорму() от ПолучитьФормуВыбора()?
ПолучитьФорму() открывает произвольную форму объекта по имени, а ПолучитьФормуВыбора() возвращает именно форму выбора, назначенную объекту в конфигураторе. Для задачи «открыть выбор с отбором» корректнее использовать ПолучитьФормуВыбора() — тогда учитывается переопределённая форма выбора конфигурации.
Почему отбор не применяется, хотя код выполняется без ошибок?
Чаще всего не установлено свойство Использование = Истина у элемента отбора либо отбор задаётся после вызова ОткрытьМодально(). Реже — имя поля указано с ошибкой или отбор очищается кодом самой формы при её создании.
Можно ли открыть форму выбора с отбором в управляемом приложении тем же кодом?
Нет. В управляемых формах используется ОткрытьФорму() с параметром «Отбор» — структурой, где ключи это имена полей. Механизм ПолучитьФормуВыбора и объект Отбор формы списка относится только к обычным формам.
Как передать в форму выбора сложное условие, которое не выразить элементом отбора?
Добавьте в форму выбора собственный реквизит-параметр, при создании формы примите значение и в обработчике ПриОткрытии установите произвольный отбор или измените запрос списка. Альтернатива для обычных форм — использовать свойство ПроизвольныйЗапрос у объекта списка с готовым текстом запроса.
Пользователь снимает отбор через кнопку настройки списка. Что делать?
Скройте или отключите кнопки отбора на командной панели табличного поля формы выбора и дублируйте критичные ограничения проверкой в модуле объекта. Интерфейсный отбор сам по себе не является надёжным ограничением.
Что важно запомнить
Отбор в обычных формах выбора задаётся через объект формы: ПолучитьФормуВыбора → добавление элементов отбора с Использование = Истина → ОткрытьМодально(). Очищайте коллекцию отбора при повторном использовании формы, ограничивайте возможность снять фильтр и дублируйте критичные ограничения проверками на уровне данных.