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