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

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

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

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

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

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

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

Как устроен механизм выбора в управляемой форме

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

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

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

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

1c
// Модуль формы выбора
&НаКлиенте
Процедура СписокВыбор(Элемент, ВыбраннаяСтрока, Поле, СтандартнаяОбработка)
    СтандартнаяОбработка = Ложь;
    ТекущиеДанные = Элемент.ТекущиеДанные;
    ОповеститьОВыборе(ТекущиеДанные.Ссылка);
КонецПроцедуры

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

1c
// Модуль вызывающей формы
&НаКлиенте
Процедура Подбор(Команда)
    ПараметрыФормы = Новый Структура("РежимВыбора", Истина);
    ОткрытьФорму("Справочник.Номенклатура.ФормаВыбора", ПараметрыФормы, Элементы.Товары);
КонецПроцедуры

&НаКлиенте
Процедура ОбработкаВыбора(ВыбранноеЗначение, ИсточникВыбора)
    НоваяСтрока = Объект.Товары.Добавить();
    НоваяСтрока.Номенклатура = ВыбранноеЗначение;
КонецПроцедуры

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

Способ 2: вернуть значение через Закрыть и ОписаниеОповещения

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

1c
// Вызывающая форма
&НаКлиенте
Процедура ВыбратьКонтрагента(Команда)
    Оповещение = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтотОбъект);
    ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , , Оповещение);
КонецПроцедуры

&НаКлиенте
Процедура ПослеВыбораКонтрагента(Результат, ДопПараметры) Экспорт
    Если Результат <> Неопределено Тогда
        Объект.Контрагент = Результат;
    КонецЕсли;
КонецПроцедуры

В форме выбора при подтверждении достаточно вызвать Закрыть(ВыбранноеЗначение). Переданное значение попадёт в параметр Результат процедуры оповещения. Важно: если пользователь закрыл форму крестиком или клавишей Esc, результат будет Неопределено — эту ситуацию нужно обрабатывать всегда, иначе возможно присвоение пустого значения реквизиту.

Способ 3: стандартный выбор для полей ввода

Если форма выбора открывается штатно — по кнопке выбора у поля ввода, связанного со ссылочным реквизитом, — писать код возврата вообще не нужно. Платформа сама устанавливает выбранное значение в реквизит. Требуется только, чтобы у формы справочника была назначена форма выбора по умолчанию или чтобы открытие происходило с параметром РежимВыбора = Истина.

Дополнительная обработка при этом тоже доступна: у элемента формы есть событие ОбработкаВыбора, где можно, например, отменить стандартное присвоение (СтандартнаяОбработка = Ложь) и заполнить несколько полей на основании выбранного значения — цену, единицу измерения, ставку НДС.

Возврат нескольких значений и сложных данных

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

1c
// Форма подбора: передаём массив структур
&НаКлиенте
Процедура ПеренестиВДокумент(Команда)
    Результат = Новый Массив;
    Для Каждого Строка Из ПодобранныеТовары Цикл
        Результат.Добавить(Новый Структура("Номенклатура, Количество, Цена",
            Строка.Номенклатура, Строка.Количество, Строка.Цена));
    КонецЦикла;
    ОповеститьОВыборе(Результат);
КонецПроцедуры

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

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

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

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

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

Удобен для разового выбора с обработкой в точке вызова. Форма закрывается после выбора, множественный подбор неудобен.

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

Работает без кода для ссылочных реквизитов. Гибкость ограничена событием ОбработкаВыбора элемента.

Временное хранилище

Для больших объёмов данных из подбора. Требует серверного вызова для чтения и контроля времени жизни хранилища.

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

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

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

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

Срабатывание обработчика
Норма

Точка останова в ОбработкаВыбора или процедуре оповещения останавливает выполнение

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

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

Содержимое значения
Норма

В параметре приходит ожидаемая ссылка, структура или массив

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

Приходит Неопределено при подтверждённом выборе — проверьте аргумент Закрыть()

Отмена выбора
Норма

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

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

Реквизит очищается или возникает ошибка — нет проверки на Неопределено

Типичные ошибки
01
Открытие формы без владельца: ОткрытьФорму(...) без третьего параметра — ОбработкаВыбора никогда не сработает.
02
Использование ОткрытьФормуМодально: метод не поддерживается в веб-клиенте и блокируется в таксометри-режиме интерфейса; заменяйте на ОткрытьФорму с ОписаниеОповещения.
03
Отсутствие проверки Результат <> Неопределено: при отмене выбора реквизит затирается пустым значением.
04
Процедура оповещения без Экспорт: платформа выдаёт ошибку 'Процедура не обнаружена' при закрытии формы.
05
Передача таблицы значений между формами: тип недоступен на клиенте в управляемом приложении — используйте массив структур или хранилище.

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

Ограничения и безопасные границы изменений

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

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

Итог

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

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

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

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

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

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

Используйте ОповеститьОВыборе без вызова Закрыть. Форма подбора останется открытой, пользователь сможет выбирать следующие строки, а каждый выбор будет приходить в ОбработкаВыбора вызывающей формы.

Можно ли использовать ОткрытьФормуМодально для возврата значения?

Технически в тонком клиенте с включённым режимом модальности это работает, но в веб-клиенте и при стандартных настройках совместимости метод недоступен. Рекомендуемая замена — ОткрытьФорму с ОписаниеОповещения.

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

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

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

В обычных формах используется ОткрытьФормуМодально, которая возвращает значение, переданное в метод Закрыть, напрямую в переменную. Событие ОбработкаВыбора там тоже доступно через ОповеститьОВыборе.

Что делать, если нужно отличить отмену выбора от выбора пустого значения?

При отмене через Закрыть без параметра результат равен Неопределено. Если пустое значение является осмысленным результатом, передавайте его явно (например, пустую ссылку) и обрабатывайте отдельно от Неопределено в процедуре оповещения.