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