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

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

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

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

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

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

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

Как устроен механизм возврата значения

В управляемом приложении форма выбора и форма-владелец связаны через свойство ВладелецФормы. Когда пользователь открывает выбор из поля ввода, платформа сама назначает владельца и сама обрабатывает результат: выбранное значение подставляется в поле без единой строки кода. Это стандартный сценарий, который работает «из коробки».

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

Стандартный выбор через поле ввода

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

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

&НаКлиенте

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

Если Не КонтрагентАктивен(ВыбранноеЗначение) Тогда

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

ПоказатьПредупреждение(, "Контрагент заблокирован, выбор отменён");

КонецЕсли;

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

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

Когда выбор открывается по кнопке, нужно явно задать владельца. При вызове ОткрытьФорму третьим параметром передаётся владелец — тогда ОповеститьОВыборе в форме выбора дойдёт именно до нужной формы, и у неё сработает ОбработкаВыбора.

&НаКлиенте

Процедура ПодобратьНоменклатуру(Команда)

ПараметрыФормы = Новый Структура("РежимВыбора", Истина);

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

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

&НаКлиенте

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

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

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

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

КонецЕсли;

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

В самой форме выбора важно, чтобы параметр РежимВыбора был обработан: установите РежимВыбора у динамического списка в Истина в обработчике ПриСозданииНаСервере. Тогда платформа сама будет вызывать ОповеститьОВыборе при двойном клике по строке.

Порядок действий для программного выбора
  1. 1
    Создайте форму выбора у объекта метаданных или используйте автогенерируемую
  2. 2
    В вызывающей форме откройте её через ОткрытьФорму с параметром РежимВыбора = Истина и владельцем ЭтотОбъект
  3. 3
    В форме выбора обеспечьте вызов ОповеститьОВыборе при выборе строки (платформа делает это сама при включённом режиме выбора)
  4. 4
    В форме-владельце реализуйте ОбработкаВыбора и проверьте тип пришедшего значения
  5. 5
    Проверьте результат: после двойного клика строка должна появиться в табличной части

Возврат значения через Закрыть и ОписаниеОповещения

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

&НаКлиенте

Процедура ВыбратьСклад(Команда)

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

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

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

&НаКлиенте

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

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

Объект.Склад = Результат;

КонецЕсли;

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

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

Возврат произвольных данных: структуры и множественный выбор

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

&НаКлиенте

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

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

ДанныеСтроки = Элементы.Список.ТекущиеДанные;

Результат = Новый Структура;

Результат.Вставить("Номенклатура", ДанныеСтроки.Ссылка);

Результат.Вставить("Цена", ДанныеСтроки.Цена);

ОповеститьОВыборе(Результат);

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

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

Сравнение способов возврата

Стандартный выбор поля ввода

Нулевой код, но нет гибкости: подходит только для простой подстановки ссылки в реквизит

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

Универсально для программного открытия; один обработчик на форму, нужно различать источники по типу значения

Закрыть(Значение) + ОписаниеОповещения

Локальная обработка результата у конкретной команды; требует проверки на Неопределено при отмене

Проверка результата и типовые ошибки

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

Типичные ошибки
01
Не указан владелец при ОткрытьФорму — ОбработкаВыбора у нужной формы не срабатывает, значение теряется
02
Не установлен РежимВыбора у динамического списка — двойной клик открывает элемент вместо его выбора
03
Нет проверки Результат <> Неопределено после Закрыть — отмена выбора затирает заполненный реквизит
04
В ОбработкаВыбора не проверяется тип значения — выбор из другой формы-владельца обрабатывается ошибочно
05
Используется модальное открытие — код не работает в веб-клиенте и при запрещённой модальности

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

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

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

Выбор строки в форме выбора
Норма

Значение появляется в поле или табличной части вызывающей формы

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

Форма выбора закрывается, но ничего не заполняется

Закрытие формы без выбора
Норма

Реквизиты вызывающей формы остаются без изменений

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

Поле очищается или возникает ошибка

Повторный выбор
Норма

Новое значение корректно заменяет предыдущее

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

Добавляются дубли строк или открывается вторая форма выбора

Итог

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

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

Частые вопросы

Почему ОбработкаВыбора не срабатывает после выбора?

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

Как вернуть значение, если форма выбора открыта из общего модуля?

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

Можно ли вернуть несколько значений за один выбор?

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

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

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

Как отменить стандартную подстановку значения в поле ввода?

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

Работает ли возврат через Закрыть в веб-клиенте?

Да, немодальное закрытие с передачей значения и ОписаниеОповещения полностью поддерживаются в веб-клиенте и тонком клиенте. Не работают только модальные методы вроде ОткрытьФормуМодально при запрещённом режиме модальности.