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