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

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

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

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

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

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

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

Как платформа 1С передаёт данные между формами

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

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

Способ 1: вернуть значение через Закрыть(Результат)

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

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

&НаКлиенте

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

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

ОткрытьФорму("Справочник.Контрагенты.Форма.ФормаПодбора", , ЭтотОбъект, , , ,

Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

&НаКлиенте

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

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

Объект.Контрагент = Результат;

КонецЕсли;

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

// Код в открываемой форме подбора

&НаКлиенте

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

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

Если ТекущиеДанные <> Неопределено Тогда

Закрыть(ТекущиеДанные.Ссылка);

Иначе

Закрыть(Неопределено);

КонецЕсли;

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

Обратите внимание на обязательную проверку Результат <> Неопределено: если пользователь закрыл форму крестиком или клавишей Esc, метод Закрыть() с параметром не вызывался, и в обработчик придёт Неопределено. Пропуск этой проверки — частая причина ошибок «Значение не является значением объектного типа».

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

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

// В форме подбора

&НаКлиенте

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

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

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

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

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

// В форме-владельце (например, документа)

&НаКлиенте

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

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

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

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

КонецЕсли;

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

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

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

Способ 3: вернуть структуру или несколько значений

Через Закрыть() и ОповеститьОВыборе() можно передать не одно значение, а структуру с произвольным набором полей. Это удобно, когда форма настроек должна вернуть сразу несколько параметров: период, флажки, выбранные ссылки.

&НаКлиенте

Процедура ПрименитьНастройки(Команда)

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

Результат.Вставить("НачалоПериода", НачалоПериода);

Результат.Вставить("КонецПериода", КонецПериода);

Результат.Вставить("ВключатьАрхив", ВключатьАрхив);

Закрыть(Результат);

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

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

Возврат значения из формы, открытой программно без владельца

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

Глобальное оповещение: форма вызывает Оповестить("ВыбранКонтрагент", Значение, ЭтотОбъект), а все заинтересованные формы обрабатывают событие в ОбработкаОповещения(ИмяСобытия, Параметр, Источник). Это удобно для обновления открытых списков, но для передачи результата конкретному вызывающему коду предпочтительнее описание оповещения — оно адресное и не требует фильтрации событий.

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

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

Лучший вариант для диалогов и форм настроек с блокировкой владельца. Адресная доставка результата, форма закрывается.

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

Стандарт для подборов: форма остаётся открытой, владелец получает событие в ОбработкаВыбора. Требует формы-владельца.

Оповестить() глобально

Подходит для уведомления нескольких открытых форм об изменении данных. Не годится для адресного возврата результата.

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

Дополнение к остальным способам, когда возвращаемый объём данных велик (таблицы значений, результаты подбора).

Типичные ошибки и как их избежать

Первая частая проблема — обработчик оповещения объявлен без директивы Экспорт или с неверным числом параметров. Процедура обработчика всегда принимает два параметра: результат и дополнительные параметры описания оповещения. Если сигнатура не совпадает, платформа выдаст ошибку при срабатывании оповещения.

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

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

Типичные ошибки
01
Нет проверки Результат &lt;&gt; Неопределено — при закрытии формы крестиком обработчик получает Неопределено и падает с ошибкой.
02
Обработчик оповещения без Экспорт или с одним параметром — оповещение не срабатывает или вызывает исключение.
03
Открытие формы без указания владельца при использовании ОповеститьОВыборе — событие уходит в никуда.
04
Передача в структуре несериализуемых объектов — ошибка при обмене клиент-сервер.
05
Использование модальных вызовов при отключённом режиме модальности — код не выполняется.

Как проверить, что значение возвращается корректно

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

Далее проверьте тип возвращаемого значения: для ссылок используйте ТипЗнч(), для структур — проверку наличия ключей через Результат.Свойство("ИмяКлюча"). Это защитит от ситуации, когда форма вернула Неопределено или данные другого состава.

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

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

Вызов обработчика
Норма

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

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

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

Содержимое результата
Норма

Результат содержит ожидаемое значение или структуру с нужными ключами

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

Приходит Неопределено — форма закрыта без вызова Закрыть(Значение)

Поведение при отмене
Норма

При закрытии крестиком вызывающий код корректно обрабатывает Неопределено

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

Ошибка при отмене выбора пользователем

FAQ

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

Да. Используйте ОповеститьОВыборе(Значение) — событие придёт в ОбработкаВыбора формы-владельца, а сама форма останется открытой. Либо глобальное Оповестить() для уведомления любых открытых форм.

Почему в обработчик приходит Неопределено, хотя я передаю значение?

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

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

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

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

Да, все описанные механизмы (ОписаниеОповещения, Закрыть с параметром, оповещения) работают в веб-клиенте. Не работают только модальные вызовы без описаний оповещений — поэтому их и следует избегать.

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

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

Итог

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

Для диалогов и настроек возвращайте значение через Закрыть(Результат) с описанием оповещения; для подборов — через ОповеститьОВыборе и ОбработкаВыбора у владельца. Всегда проверяйте результат на Неопределено, объявляйте обработчики с Экспорт и двумя параметрами, а большие данные передавайте через временное хранилище.