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

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

1С: как вернуть выбранное значение из формы выбора

Как в 1С вернуть выбранное значение из формы выбора: ОбработкаВыбора, ОповеститьОВыборе, ПоказатьВводЗначения, примеры кода и типичные ошибки.

Задача «вернуть выбранное значение» возникает в 1С постоянно: пользователь открывает форму выбора справочника, отмечает элемент, и это значение нужно передать обратно — в поле ввода, в табличную часть документа или в параметр отчёта. Платформа предлагает несколько механизмов для этого, и выбор конкретного зависит от того, как открывается форма: стандартно через поле ввода или программно.

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

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

Как работает механизм выбора значения в 1С

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

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

Стандартный выбор через поле ввода и событие ОбработкаВыбора

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

&НаКлиенте

Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)

Если ТипЗнч(ВыбранноеЗначение) = Тип("СправочникСсылка.Номенклатура") Тогда

Объект.ОсновнаяНоменклатура = ВыбранноеЗначение;

КонецЕсли;

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

Параметр ВыбранноеЗначение содержит то, что передала форма выбора: ссылку, массив при множественном выборе или произвольную структуру. Параметр ИсточникВыбора — это сама форма выбора, по нему можно различать, откуда пришло значение, если на форме несколько полей выбора.

Важно: если вы обрабатываете выбор вручную, стандартная обработка поля ввода может продолжить работать параллельно. Чтобы избежать двойного присвоения, либо полностью берите выбор на себя через событие Выбор элемента формы с установкой СтандартнаяОбработка = Ложь, либо не смешивайте оба подхода для одного поля.

Программное открытие формы выбора с отбором

Когда выбор нужно инициировать из своей команды — например, по кнопке «Подобрать товары» — форму выбора открывают программно с параметрами. Параметры позволяют задать отбор, режим выбора и владельца:

&НаКлиенте

Процедура ПодобратьТовары(Команда)

ПараметрыФормы = Новый Структура;

ПараметрыФормы.Вставить("РежимВыбора", Истина);

ПараметрыФормы.Вставить("МножественныйВыбор", Истина);

ПараметрыФормы.Вставить("Отбор", Новый Структура("ПометкаУдаления", Ложь));

ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора",

ПараметрыФормы, ЭтотОбъект, УникальныйИдентификатор);

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

Третий параметр ОткрытьФорму() — владелец формы. Именно он определяет, куда придёт оповещение о выборе. Если владельца не указать, событие ОбработкаВыбора у вашей формы не сработает — это одна из самых частых причин «молчащего» кода.

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

&НаКлиенте

Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)

Если ТипЗнч(ВыбранноеЗначение) = Тип("Массив") Тогда

Для Каждого Элемент Из ВыбранноеЗначение Цикл

НоваяСтрока = Объект.Товары.Добавить();

НоваяСтрока.Номенклатура = Элемент;

КонецЦикла;

КонецЕсли;

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

Порядок действий при программном выборе
  1. 1
    Сформируйте структуру параметров: РежимВыбора, Отбор, МножественныйВыбор
  2. 2
    Вызовите ОткрытьФорму, передав ЭтотОбъект владельцем
  3. 3
    Добавьте у формы-владельца обработчик ОбработкаВыбора
  4. 4
    Проверьте тип пришедшего значения: ссылка или массив
  5. 5
    Заполните реквизит или табличную часть и проверьте результат

Возврат значения через ОповеститьОВыборе из произвольной формы

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

&НаКлиенте

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

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

ОповеститьОВыборе(Элементы.Список.ТекущиеДанные.Ссылка);

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

Метод ОповеститьОВыборе() автоматически закрывает форму выбора, если она открыта в режиме выбора, и передаёт значение владельцу. Аргументом может быть не только ссылка: допустимо передать структуру с несколькими полями, например ссылку и цену, если владельцу нужен расширенный результат.

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

Способы вернуть выбранное значение

ОповеститьОВыборе

Стандартный способ для форм выбора; результат приходит в ОбработкаВыбора владельца. Ограничение: работает только с владельцем формы.

Оповестить + ОбработкаОповещения

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

ПоказатьВводЗначения

Для ввода простых значений: строка, число, дата, ссылка. Результат приходит в описание оповещения, событие ОбработкаВыбора не используется.

Ввод значения через ПоказатьВводЗначения

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

&НаКлиенте

Процедура УказатьСклад(Команда)

ОписаниеОповещения = Новый ОписаниеОповещения("ПослеВводаСклада", ЭтотОбъект);

ПоказатьВводЗначения(ОписаниеОповещения, ,

"Выберите склад", Тип("СправочникСсылка.Склады"));

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

&НаКлиенте

Процедура ПослеВводаСклада(Значение, ДополнительныеПараметры) Экспорт

Если Значение <> Неопределено Тогда

Объект.Склад = Значение;

КонецЕсли;

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

Обратите внимание на проверку Значение <> Неопределено: если пользователь нажал «Отмена», в обработчик придёт Неопределено, и без проверки вы затрёте текущее значение реквизита пустотой. Эта проверка обязательна во всех асинхронных обработчиках результата.

Типичные ошибки
01
Не указан владелец при ОткрытьФорму — ОбработкаВыбора у формы никогда не вызывается
02
Нет проверки на Неопределено в обработчике оповещения — при отмене ввода реквизит очищается
03
Перепутаны ОбработкаВыбора и ОбработкаОповещения — код написан, но событие приходит в другой обработчик
04
Ожидание возврата значения из ОткрытьФорму как из функции — метод ничего не возвращает, результат приходит только через событие
05
Двойная обработка: одновременно стандартный выбор поля и ручной код в ОбработкаВыбора приводят к дублям

Модальный режим и его ограничения

В старых конфигурациях на обычных формах и в ранних версиях управляемого приложения использовался модальный метод ОткрытьФормуМодально(), который останавливал выполнение кода и возвращал выбранное значение напрямую. В современных конфигурациях режим модальности обычно запрещён свойством конфигурации «Режим использования модальности», а веб-клиент модальные окна не поддерживает вовсе.

Поэтому при доработке старого кода модальные вызовы заменяют на асинхронные аналоги: ПоказатьВводЗначения вместо ВвестиЗначение, открытие формы с описанием оповещения вместо ОткрытьФормуМодально. Логика «после выбора» переносится в процедуру-обработчик оповещения.

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

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

Для отладки механизма выбора удобно временно добавить в ОбработкаВыбора вывод типа значения через Сообщить(ТипЗнч(ВыбранноеЗначение)) — так сразу видно, доходит ли событие до формы и что именно передаёт источник. Если обработчик не срабатывает, первым делом проверяйте владельца при открытии формы и наличие у формы выбора вызова ОповеститьОВыборе().

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

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

Срабатывает ли ОбработкаВыбора
Норма

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

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

Обработчик не вызывается — проверьте владельца в ОткрытьФорму и вызов ОповеститьОВыборе

Тип полученного значения
Норма

Тип соответствует ожиданию: ссылка при одиночном выборе, массив при множественном

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

Пришёл массив вместо ссылки или Неопределено — значит, перепутан режим выбора или пользователь отменил ввод

Значение в реквизите после выбора
Норма

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

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

Реквизит очищен или строки задублированы — проверьте обработку отмены и повторного выбора

Частые вопросы о возврате выбранного значения

Почему ОбработкаВыбора не вызывается, хотя форма выбора открывается?

Чаще всего при открытии формы не указан владелец — третий параметр ОткрытьФорму(). Без владельца платформе некому отправлять оповещение. Вторая причина — форма выбора не вызывает ОповеститьОВыборе(), например, выбор сделан программно в обход стандартного механизма.

Как вернуть из формы выбора несколько значений сразу?

Включите множественный выбор параметром МножественныйВыбор = Истина при открытии формы. Тогда в ОбработкаВыбора придёт массив ссылок. Либо передайте из своей формы структуру или массив через ОповеститьОВыборе() вручную.

Чем ОповеститьОВыборе отличается от Оповестить?

ОповеститьОВыборе() отправляет результат только владельцу формы и закрывает форму выбора. Оповестить() рассылает именованное событие всем открытым формам, которые его обрабатывают в ОбработкаОповещения, и не закрывает форму автоматически.

Как получить значение, если пользователь нажал «Отмена»?

При отмене в асинхронный обработчик приходит Неопределено. Всегда проверяйте это перед присвоением: Если Значение <> Неопределено Тогда ... — иначе отмена ввода сотрёт ранее заполненный реквизит.

Можно ли вернуть значение из формы, открытой не из поля ввода?

Да. Укажите свою форму владельцем при ОткрытьФорму и реализуйте у неё ОбработкаВыбора. Механизм не привязан к полям ввода — он работает для любой пары «форма-владелец / форма выбора».

Итог

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

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