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

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

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

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

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

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

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

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

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

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

ПараметрыФормы.Вставить("Контрагент", ТекущийКонтрагент);

ПараметрыФормы.Вставить("ДатаОтгрузки", ТекущаяДатаСеанса());

ОткрытьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаПодбора", ПараметрыФормы, ЭтотОбъект);

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

&НаСервере

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

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

Контрагент = Параметры.Контрагент;

КонецЕсли;

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

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

Ключ уникальности и повторное открытие формы

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

ОткрытьФорму("Обработка.НастройкаОтбора.Форма.ФормаНастройки",

ПараметрыФормы, ЭтотОбъект, СсылкаНаОбъект);

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

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

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

// В форме-источнике

Оповестить("ИзмененКонтрагент", НовыйКонтрагент, ЭтотОбъект);

// В форме-приёмнике

&НаКлиенте

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

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

Контрагент = Параметр;

КонецЕсли;

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

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

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

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

Возврат значения из формы выбора

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

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

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

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

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

В форме выбора по команде «Выбрать» вызывается:

&НаКлиенте

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

Закрыть(ТекущийЭлемент);

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

А в открывающей форме результат попадает в первый параметр процедуры-обработчика:

&НаКлиенте

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

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

Возврат; // пользователь закрыл форму без выбора

КонецЕсли;

Товар = Результат;

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

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

Стандартный механизм ОповеститьОВыборе

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

Порядок действий при передаче через оповещение
  1. 1
    В форме-приёмнике создайте обработчик ОбработкаОповещения с проверкой ИмяСобытия
  2. 2
    В форме-источнике вызовите Оповестить с тем же именем события и нужным значением
  3. 3
    Передайте третьим параметром источник, чтобы приёмник мог отфильтровать чужие события
  4. 4
    Откройте обе формы и проверьте, что значение появляется в приёмнике
  5. 5
    Проверьте поведение при закрытой форме-приёмнике — ошибок быть не должно

Передача больших данных через временное хранилище

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

// В форме-источнике (на сервере)

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

// В форме-приёмнике (на сервере)

ТаблицаТоваров = ПолучитьИзВременногоХранилища(Параметры.АдресВХранилище);

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

Выбор подходящего способа

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

СитуацияМеханизмОграничение
Данные известны до открытия формыПараметры ОткрытьФормуЧитаются только при создании формы
Обе формы уже открытыОповестить / ОбработкаОповещенияНет гарантии, что приёмник существует
Результат из формы выбораЗакрыть + ОписаниеОповещенияНужно обрабатывать отмену выбора
Выбор из поля вводаОповеститьОВыборе / ОбработкаВыбораРаботает только с формой-владельцем
Большие таблицы, результаты запросовВременное хранилищеНужно управлять временем жизни данных
Маршрут решения

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

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

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

Главная сложность при передаче между формами — ошибки проявляются молча: оповещение не дошло, параметр не прочитан, а платформа не сообщает об этом. Поэтому после внедрения проверьте цепочку целиком: поставьте точку останова в ПриСозданииНаСервере формы-приёмника и убедитесь, что Параметры содержит нужные ключи; в ОбработкаОповещения проверьте, что событие приходит с правильным именем и непустым параметром.

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

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

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

Содержимое Параметры в ПриСозданииНаСервере
Норма

Все переданные ключи присутствуют и имеют ожидаемый тип

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

Ключа нет или значение Неопределено — проверяйте состав структуры при вызове ОткрытьФорму

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

Обработчик вызывается с нужным ИмяСобытия сразу после Оповестить

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

Обработчик не вызывается — ищите опечатку в имени события или закрытую форму-приёмник

Результат в ОписаниеОповещения после закрытия формы выбора
Норма

При выборе приходит значение, при отмене — Неопределено

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

Всегда Неопределено — в форме выбора Закрыть вызывается без параметра

Часто задаваемые вопросы

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

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

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

Чаще всего причины три: опечатка в имени события в одном из мест, форма-приёмник закрыта в момент отправки, либо обработчик объявлен без директивы &НаКлиенте. Добавьте вывод имени события в начало обработчика — это сразу покажет, доходят ли оповещения до формы.

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

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

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

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

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

Передайте в Закрыть() структуру с нужными ключами, например Закрыть(Новый Структура("Товар, Количество", Товар, Количество)). В обработчике ОписаниеОповещения разберите структуру по ключам. Альтернатива — поместить набор данных во временное хранилище и вернуть адрес.

Нужно ли удалять данные из временного хранилища?

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

Итог

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

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