Разработка и Конфигурация · 12 мин
Как передать значение из формы в форму в 1С
Способы передачи значений между формами в 1С 8.3: параметры формы, ОписаниеОповещения, Оповестить, временное хранилище. Примеры кода, ошибки и проверка результата.
Передача значений между формами — одна из базовых задач разработки на платформе 1С:Предприятие 8.3. Открыть форму выбора и получить выбранный элемент, пробросить отбор в форму списка, вернуть результат редактирования из диалога — всё это решается тремя основными механизмами: параметры формы, оповещения о закрытии и метод Оповестить(). Выбор зависит от направления передачи: из вызывающей формы в открываемую или обратно.
Главная сложность для начинающих разработчиков — понять, что формы в управляемом интерфейсе не имеют прямого доступа друг к другу. Нельзя «дотянуться» до реквизита чужой формы напрямую, как это делалось в обычных формах через ПолучитьФорму(). Вместо этого платформа предлагает контракт: вы передаёте данные при открытии, а результат получаете через оповещение или закрывающее значение.
Ниже разобраны рабочие способы с примерами кода, их ограничения и типичные ошибки. Примеры приведены для управляемых форм в режиме тонкого клиента; синтаксис одинаково работает в большинстве типовых и самописных конфигураций.
Как выбрать способ передачи значения
Прежде чем писать код, определите направление и характер передачи. Если данные нужны форме в момент открытия (отбор, режим работы, ключ записи) — используйте параметры формы. Если открываемая форма должна вернуть результат (выбранный элемент, введённое значение) — используйте оповещение о закрытии. Если формы живут одновременно и должны реагировать на события друг друга — подойдёт механизм Оповестить/ОбработкаОповещения.
Отдельный случай — передача больших или сложных данных (таблицы значений, результаты запросов). Их нельзя передать напрямую через параметры, потому что параметры формы сериализуются и поддерживают ограниченный набор типов. Здесь применяют временное хранилище: данные кладут туда на сервере, а между формами передают только адрес хранилища.
Как выбрать действие
Передача значения при открытии формы через параметры
Самый частый сценарий: из формы документа нужно открыть форму списка с отбором или передать в форму обработки начальные данные. Для этого у метода ОткрытьФорму() есть второй позиционный параметр — структура, ключи которой становятся параметрами открываемой формы.
Пример кода вызывающей формы:
&НаКлиенте
Процедура ОткрытьПодбор(Команда)
ПараметрыФормы = Новый Структура;
ПараметрыФормы.Вставить("Организация", Объект.Организация);
ПараметрыФормы.Вставить("Склад", Объект.Склад);
ОткрытьФорму("Справочник.Номенклатура.Форма.ФормаПодбора",
ПараметрыФормы, ЭтаФорма, УникальныйИдентификатор);
КонецПроцедуры
В открываемой форме значения доступны через свойство Параметры в обработчике ПриСозданииНаСервере:
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
Если Параметры.Свойство("Организация") Тогда
ТекущаяОрганизация = Параметры.Организация;
КонецЕсли;
КонецПроцедуры
Обратите внимание на проверку Параметры.Свойство() — она обязательна. Если форму откроют без параметра (например, из другого места программы), обращение к несуществующему ключу вызовет ошибку. Дополнительно параметры можно объявить явно в свойствах формы на закладке «Параметры» — тогда они станут типизированными, и платформа сама будет контролировать их состав.
Получение результата обратно через оповещение о закрытии
Когда открываемая форма — это диалог, который должен вернуть значение (форма выбора, ввод строки, настройка), результат передают через параметр метода Закрыть(). Вызывающая форма получает его в обработчике, описанном объектом ОписаниеОповещения.
Код вызывающей формы:
&НаКлиенте
Процедура ВыбратьКонтрагента(Команда)
Оповещение = Новый ОписаниеОповещения("ПослеВыбораКонтрагента", ЭтаФорма);
ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", ,
ЭтаФорма, , , , Оповещение, РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ПослеВыбораКонтрагента(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
Объект.Контрагент = Результат;
КонецЕсли;
КонецПроцедуры
В форме выбора достаточно вернуть значение при закрытии:
&НаКлиенте
Процедура Выбрать(Команда)
Закрыть(Элементы.Список.ТекущиеДанные.Ссылка);
КонецПроцедуры
Если пользователь закрыл форму крестиком, в обработчик придёт Неопределено — поэтому проверка результата обязательна. Имя процедуры-обработчика передаётся строкой, и она должна быть объявлена с директивой Экспорт, иначе платформа не сможет её вызвать.
- 1В вызывающей форме создайте ОписаниеОповещения с именем процедуры-обработчика
- 2Передайте оповещение седьмым параметром в ОткрытьФорму()
- 3Объявите процедуру-обработчик с двумя параметрами (Результат, ДополнительныеПараметры) и директивой Экспорт
- 4В открываемой форме верните значение через Закрыть(Значение)
- 5В обработчике проверьте Результат на Неопределено перед использованием
Обмен между открытыми формами через Оповестить
Если обе формы уже открыты и одна должна сообщить другой о событии (например, форма подбора сигнализирует документу о добавлении товара), используется пара методов Оповестить() и обработчик ОбработкаОповещения().
Форма-источник отправляет событие:
&НаКлиенте
Процедура ДобавитьТовар(Команда)
Оповестить("ПодобранТовар", ТекущаяНоменклатура, ЭтаФорма);
КонецПроцедуры
Форма-приёмник обрабатывает событие по имени:
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "ПодобранТовар" Тогда
ДобавитьСтрокуТовара(Параметр);
КонецЕсли;
КонецПроцедуры
Метод Оповестить рассылает событие всем открытым формам, поэтому имя события должно быть уникальным в рамках прикладного решения — иначе чужая форма с таким же обработчиком отреагирует непреднамеренно. Третий параметр (Источник) позволяет приёмнику фильтровать события и реагировать только на конкретную форму.
Передача сложных данных через временное хранилище
Когда нужно передать таблицу значений, дерево или другой объект, который не сериализуется в параметры формы, данные помещают во временное хранилище на сервере, а между формами передают только строковый адрес.
&НаСервере
Функция ПодготовитьАдресТаблицы()
ТаблицаТоваров = Объект.Товары.Выгрузить();
Возврат ПоместитьВоВременноеХранилище(ТаблицаТоваров, УникальныйИдентификатор);
КонецФункции
&НаКлиенте
Процедура ОткрытьРедакторТаблицы(Команда)
Адрес = ПодготовитьАдресТаблицы();
ПараметрыФормы = Новый Структура("АдресТаблицы", Адрес);
ОткрытьФорму("Обработка.РедакторТаблицы.Форма", ПараметрыФормы, ЭтаФорма);
КонецПроцедуры
Приёмник забирает данные методом ПолучитьИзВременногоХранилища(Адрес). Второй параметр ПоместитьВоВременноеХранилище — уникальный идентификатор формы — определяет время жизни данных: пока жива форма-владелец, хранилище не очищается. Если идентификатор не указать, данные удалятся после завершения вызова сервера, и приёмник получит пустоту.
Особый случай: форма выбора и ОповеститьОВыборе
Для стандартных форм выбора справочников и документов есть упрощённый путь. Если форма открыта в режиме выбора (параметр РежимВыбора = Истина), она сама умеет возвращать выбранное значение через Закрыть(). Дополнительно существует метод ОповеститьОВыборе(), который отправляет выбранное значение в поле ввода, из которого был инициирован выбор, — это используется при подборе в табличные части.
При открытии формы выбора из кода полезно задать владельца (третий параметр ОткрытьФорму): тогда стандартный механизм выбора сам доставит значение в нужное поле, и писать обработчик оповещения не потребуется. Если же нужна нестандартная реакция на выбор — например, дозаполнить несколько полей по выбранному элементу — комбинируйте: форма выбора возвращает ссылку через Закрыть(), а обработчик оповещения дочитывает остальные реквизиты серверным вызовом.
Как проверить результат
В ПриСозданииНаСервере Параметры.Свойство() возвращает Истина, значение корректное
Свойства нет или значение пустое — проверьте имя ключа и состав структуры при открытии
После Закрыть(Значение) выполняется процедура-обработчик, Результат заполнен
Обработчик не вызывается — проверьте Экспорт у процедуры и точное имя в ОписаниеОповещения
ПолучитьИзВременногоХранилища возвращает объект ожидаемого типа
Возвращается Неопределено — данные удалены, не передан УникальныйИдентификатор формы
Проверка результата и отладка
Быстрый способ убедиться, что передача работает, — поставить точку останова в ПриСозданииНаСервере открываемой формы и посмотреть содержимое объекта Параметры через табло. Для оповещений точку ставят в первую строку процедуры-обработчика: если управление туда не попадает, проблема в описании оповещения или в том, что форма закрылась без передачи значения.
Полезный приём при отладке Оповестить — временно добавить в ОбработкаОповещения вывод имени события через Сообщить(). Так видно, какие события вообще приходят в форму, и легко обнаружить опечатку в имени. После отладки вывод удаляют, чтобы не засорять окно сообщений пользователя.
Что важно запомнить
В открываемую форму данные передают параметрами через структуру в ОткрытьФорму(), обратно результат возвращают через Закрыть(Значение) и ОписаниеОповещения, между живыми формами — через Оповестить/ОбработкаОповещения, а сложные объекты — через временное хранилище. Всегда проверяйте наличие параметра и результат на Неопределено.
Частые вопросы
Можно ли из одной управляемой формы напрямую прочитать реквизит другой?
Штатного безопасного способа нет: управляемые формы изолированы, и обращение к чужим реквизитам считается нарушением архитектуры. Передавайте данные через параметры, оповещения или хранилище. Технический обход через ПолучитьФорму() возможен, но делает код хрупким и не поддерживается для типовых конфигураций.
Почему обработчик оповещения не вызывается, хотя форма закрылась?
Чаще всего процедура объявлена без директивы Экспорт, имя в ОписаниеОповещения не совпадает с именем процедуры, или форма закрывается без параметра — тогда в обработчик приходит Неопределено, и код с проверкой просто ничего не делает. Проверьте все три пункта отладчиком.
Как передать значение, если форма открывается из общего модуля, а не из другой формы?
Механизм тот же: ОткрытьФорму() с параметрами доступен в любом клиентском контексте. Владельца (третий параметр) можно не указывать — тогда форма будет независимой. Оповещение о закрытии тоже работает, если процедура-обработчик объявлена в клиентском общем модуле с директивой Экспорт.
Чем отличается Оповестить от ОповеститьОВыборе?
Оповестить рассылает произвольное событие всем открытым формам, и его ловят через ОбработкаОповещения. ОповеститьОВыборе — специализированный метод форм выбора: он доставляет выбранное значение в поле ввода-владельца и вызывает стандартный обработчик ОбработкаВыбора, а не ОбработкаОповещения.
Можно ли передать через параметры формы массив или структуру?
Да, массивы и структуры из сериализуемых значений (числа, строки, даты, ссылки, булево) передаются через параметры без ограничений. Не передаются объекты, существующие только на сервере: таблицы значений, результаты запросов, построители — для них используйте временное хранилище.
Что делать, если значение нужно передать в уже открытую форму?
Используйте Оповестить() с уникальным именем события: открытая форма получит его в ОбработкаОповещения и сможет обновить свои данные. Если форма может быть закрыта, сначала найдите её через Окна или просто откройте заново с параметрами — платформа активирует существующий экземпляр, если ключ уникальности совпадает.