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