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