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

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

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

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

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

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

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

Как выбрать способ передачи значения

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

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

Маршрут решения

Как выбрать действие

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

Передача значения при открытии формы через параметры

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

Пример кода вызывающей формы:

&НаКлиенте

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

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

ПараметрыФормы.Вставить("Организация", Объект.Организация);

ПараметрыФормы.Вставить("Склад", Объект.Склад);

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

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

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

В открываемой форме значения доступны через свойство Параметры в обработчике ПриСозданииНаСервере:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("Организация") Тогда

ТекущаяОрганизация = Параметры.Организация;

КонецЕсли;

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

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

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

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

Код вызывающей формы:

&НаКлиенте

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

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

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

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

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

&НаКлиенте

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

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

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

КонецЕсли;

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

В форме выбора достаточно вернуть значение при закрытии:

&НаКлиенте

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

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

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

Если пользователь закрыл форму крестиком, в обработчик придёт Неопределено — поэтому проверка результата обязательна. Имя процедуры-обработчика передаётся строкой, и она должна быть объявлена с директивой Экспорт, иначе платформа не сможет её вызвать.

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

Обмен между открытыми формами через Оповестить

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

Форма-источник отправляет событие:

&НаКлиенте

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

Оповестить("ПодобранТовар", ТекущаяНоменклатура, ЭтаФорма);

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

Форма-приёмник обрабатывает событие по имени:

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ПодобранТовар" Тогда

ДобавитьСтрокуТовара(Параметр);

КонецЕсли;

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

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

Передача сложных данных через временное хранилище

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

&НаСервере

Функция ПодготовитьАдресТаблицы()

ТаблицаТоваров = Объект.Товары.Выгрузить();

Возврат ПоместитьВоВременноеХранилище(ТаблицаТоваров, УникальныйИдентификатор);

КонецФункции

&НаКлиенте

Процедура ОткрытьРедакторТаблицы(Команда)

Адрес = ПодготовитьАдресТаблицы();

ПараметрыФормы = Новый Структура("АдресТаблицы", Адрес);

ОткрытьФорму("Обработка.РедакторТаблицы.Форма", ПараметрыФормы, ЭтаФорма);

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

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

Типичные ошибки
01
Обращение к Параметры.Ключ без проверки Свойство() — ошибка, если форму открыли без параметра
02
Процедура-обработчик оповещения объявлена без Экспорт — платформа не находит метод, оповещение не срабатывает
03
Помещение данных в хранилище без УникальныйИдентификатор формы — данные удаляются до того, как их прочитала вторая форма
04
Попытка изменить реквизит чужой формы напрямую — в управляемых формах это недоступно и приводит к ошибке
05
Использование одинаковых имён событий Оповестить в разных подсистемах — чужие формы реагируют на непредназначенные им события

Особый случай: форма выбора и ОповеститьОВыборе

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

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

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

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

Параметры дошли до открываемой формы
Норма

В ПриСозданииНаСервере Параметры.Свойство() возвращает Истина, значение корректное

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

Свойства нет или значение пустое — проверьте имя ключа и состав структуры при открытии

Оповещение о закрытии срабатывает
Норма

После Закрыть(Значение) выполняется процедура-обработчик, Результат заполнен

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

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

Данные из временного хранилища читаются
Норма

ПолучитьИзВременногоХранилища возвращает объект ожидаемого типа

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

Возвращается Неопределено — данные удалены, не передан УникальныйИдентификатор формы

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

Быстрый способ убедиться, что передача работает, — поставить точку останова в ПриСозданииНаСервере открываемой формы и посмотреть содержимое объекта Параметры через табло. Для оповещений точку ставят в первую строку процедуры-обработчика: если управление туда не попадает, проблема в описании оповещения или в том, что форма закрылась без передачи значения.

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

Итог

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

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

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

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

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

Почему обработчик оповещения не вызывается, хотя форма закрылась?

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

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

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

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

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

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

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

Что делать, если значение нужно передать в уже открытую форму?

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