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

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

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

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

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

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

Ниже разобраны оба направления передачи — «в открываемую форму» и «обратно в вызывающую», а также работа с ключом записи, стандартными параметрами расширения формы и типичные ошибки, из-за которых параметр «не доходит».

Как передать параметр при открытии формы через ОткрытьФорму

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

&НаКлиенте

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

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

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

ПараметрыФормы.Вставить("РежимТолькоПросмотр", Истина);

ОткрытьФорму("Обработка.ПодборКонтрагентов.Форма.ФормаПодбора", ПараметрыФормы, ЭтаФорма);

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

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

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

Как принять параметр в открываемой форме

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

&НаСервере

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

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

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

УстановитьОтборПоКонтрагенту(ОтборКонтрагент);

КонецЕсли;

Если Параметры.Свойство("РежимТолькоПросмотр")

И Параметры.РежимТолькоПросмотр Тогда

ЭтаФорма.ТолькоПросмотр = Истина;

КонецЕсли;

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

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

Если форма открывается повторно с теми же параметрами, платформа по умолчанию активирует уже открытый экземпляр вместо создания нового. Чтобы гарантированно получить новую форму, добавьте в структуру параметр КлючУникальности с уникальным значением, например Новый УникальныйИдентификатор.

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

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

&НаКлиенте

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

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

ПараметрыФормы = Новый Структура("Склад", Склад);

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

ПараметрыФормы, ЭтаФорма, , , , Оповещение,

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

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

&НаКлиенте

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

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

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

КонецЕсли;

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

НоваяСтрока.Номенклатура = Результат.Номенклатура;

НоваяСтрока.Количество = Результат.Количество;

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

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

&НаКлиенте

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

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

Результат.Вставить("Номенклатура", ТекущаяНоменклатура);

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

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

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

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

Альтернатива: ОповеститьОВыборе и Оповестить

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

&НаКлиенте

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

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

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

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

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

Сравнение способов обратной передачи

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

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

ОповеститьОВыборе + ОбработкаВыбора

Подходит для множественного подбора без закрытия формы подбора

Оповестить + ОбработкаОповещения

Универсальный механизм для любых событий между любыми открытыми формами, требует дисциплины в именах событий

Стандартные параметры и ключ записи

Платформа резервирует ряд стандартных параметров, которые обрабатываются автоматически. Самый востребованный — Ключ: если передать в форму элемента структуру с ключом «Ключ» и ссылкой, откроется карточка именно этого объекта. Для формы записи регистра сведений в «Ключ» передают значение типа РегистрСведенийКлючЗаписи.

ПараметрыФормы = Новый Структура("Ключ", СсылкаНаЭлемент);

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

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

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

Типичные ошибки и как их проверить

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

Вторая группа ошибок связана с оповещениями: процедура-обработчик объявлена без ключевого слова Экспорт (описание оповещения её не найдёт), обработчик не проверяет Результат = Неопределено и падает при закрытии формы крестиком, либо оповещение создано в контексте формы, которая к моменту срабатывания уже закрыта.

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

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

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

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

Параметр дошёл до формы
Норма

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

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

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

Результат вернулся обратно
Норма

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

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

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

Форма ведёт себя корректно
Норма

Форма блокирует владельца и закрывается вместе с ним

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

Форма живёт самостоятельно — не указан владелец при открытии

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

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

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

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

Таблицу значений можно вложить в структуру параметров как обычное значение — она сериализуется. На принимающей стороне в ПриСозданииНаСервере загрузите её в реквизит формы типа «ТаблицаЗначений» методом ЗначениеВРеквизитФормы или обойдите в цикле и заполните данные формы.

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

Чаще всего процедура-обработчик объявлена без Экспорт, либо форма-владелец оповещения уже закрыта к моменту вызова. Также проверьте, что форма закрывается именно через Закрыть(Результат), а не через стандартную кнопку закрытия без передачи значения — в последнем случае обработчик вызовется с Результат = Неопределено.

Чем отличается Закрыть(Результат) от ОповеститьОВыборе()?

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

Как открыть форму нового элемента с заполненными реквизитами?

Передайте в структуре параметров стандартный параметр ЗначенияЗаполнения — структуру, где ключи совпадают с именами реквизитов объекта. Форма нового элемента автоматически заполнит эти реквизиты при создании, дополнительный код в ПриСозданииНаСервере не потребуется.

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

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

Итог

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

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