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