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

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

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

Способы передачи данных между формами 1С: параметры открытия, ОповеститьОВыборе, временное хранилище, контекст. Примеры кода, ошибки и проверка результата.

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

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

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

Какие механизмы передачи данных есть в платформе

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

Способы передачи данных между формами

Параметры формы (ОткрытьФорму)

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

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

Стандартный возврат результата из модальной или немодальной формы выбора в вызывающий код. Требует корректного указания владельца.

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

Асинхронная передача данных между уже открытыми формами. Удобно для обновления списков, но сложнее отлаживать.

Временное хранилище (ПоместитьВоВременноеХранилище)

Передача больших объёмов: таблиц значений, двоичных данных, результатов компоновки. Между формами передаётся только адрес хранилища.

КлючУникальности и реквизиты формы

Контроль повторного открытия и хранение переданных данных внутри формы. Дополняет остальные механизмы.

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

Передача параметров при открытии формы

Основной способ передать данные в открываемую форму — третий параметр метода ОткрытьФорму(). Это структура, ключи которой становятся параметрами формы:

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

ПараметрыФормы.Вставить("Организация", Организация);

ПараметрыФормы.Вставить("НачалоПериода", НачалоМесяца(ТекущаяДатаСеанса()));

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

ПараметрыФормы, ЭтаФорма, УникальныйИдентификатор);

В открываемой форме переданные значения доступны через свойство Параметры в обработчике ПриСозданииНаСервере:

&НаСервере

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

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

ОрганизацияОтбор = Параметры.Организация;

КонецЕсли;

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

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

Стандартные параметры: Ключ, Отбор, ЗначенияЗаполнения

Для форм объектов и списков платформа резервирует стандартные имена параметров. Ключ открывает форму конкретного объекта по ссылке, Отбор накладывает отбор на динамический список, ЗначенияЗаполнения заполняет реквизиты нового объекта при создании:

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

ПараметрыФормы.Вставить("ЗначенияЗаполнения",

Новый Структура("Организация,Контрагент", Организация, Контрагент));

ОткрытьФорму("Документ.РеализацияТоваровУслуг.Форма.ФормаДокумента", ПараметрыФормы);

Использование стандартных параметров предпочтительнее собственных имён там, где они покрывают задачу: меньше кода в ПриСозданииНаСервере и меньше риск конфликта имён при обновлении конфигурации.

Возврат результата из открытой формы

Параметры работают только в одну сторону. Чтобы получить выбранное значение обратно, используют связку «описание оповещения + ОповеститьОВыборе».

В вызывающей форме создают описание оповещения с именем процедуры-обработчика:

&НаКлиенте

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

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

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

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

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

&НаКлиенте

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

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

Объект.Товар = Результат;

КонецЕсли;

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

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

&НаКлиенте

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

ОповеститьОВыборе(ТекущаяСтрокаТовара);

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

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

Две тонкости, о которых часто забывают. Во-первых, процедура-обработчик обязательно должна быть экспортной — иначе платформа не сможет её вызвать. Во-вторых, если форма закрыта крестиком или по Escape, обработчик всё равно вызывается, но с Результат = Неопределено; пропуск этой проверки приводит к записи пустых значений в объект.

Передача данных между уже открытыми формами

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

// В форме-источнике

Оповестить("ИзмененПоДокумент", Новый Структура("Документ", СсылкаНаДокумент), ЭтаФорма);

// В форме-приёмнике

&НаКлиенте

Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)

Если ИмяСобытия = "ИзмененПоДокумент" Тогда

Элементы.Список.Обновить();

КонецЕсли;

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

Имя события — произвольная строка, договорённость между формами. Выбирайте уникальные префиксы (например, по имени своей подсистемы), чтобы не перехватывать чужие оповещения и не реагировать на стандартные события платформы вроде Запись_Номенклатура.

Передача больших объёмов через временное хранилище

Таблицу значений на тысячи строк, результат СКД или двоичные данные через параметры передавать не стоит — это замедлит открытие формы и увеличит трафик между клиентом и сервером. Вместо этого данные помещают во временное хранилище, а между формами передают только адрес:

&НаСервере

Функция ПодготовитьДанныеДляПодбора()

АдресХранилища = ПоместитьВоВременноеХранилище(

ТаблицаТоваров.Выгрузить(), УникальныйИдентификатор);

Возврат АдресХранилища;

КонецФункции

В приёмнике данные извлекают методом ПолучитьИзВременногоХранилища(Адрес). Второй параметр ПоместитьВоВременноеХранилище — идентификатор формы — определяет время жизни хранилища: данные живут, пока существует форма с этим идентификатором. Если не указать его, данные удалятся после ближайшего серверного вызова, и приёмник получит пустое значение.

Типичные ошибки при передаче данных
01
Не указан УникальныйИдентификатор формы при помещении в хранилище — данные удаляются до чтения, приёмник получает Неопределено
02
Процедура-обработчик оповещения объявлена без Экспорт — платформа не находит метод, выбор молча не обрабатывается
03
Передача изменяемых данных через параметры с ожиданием, что изменения вернутся в родительскую форму — параметры копируются, обратной связи нет
04
Отсутствие проверки Результат на Неопределено в обработчике — закрытие формы крестиком затирает данные объекта
05
Перехват чужих оповещений из-за слишком общего имени события вроде 'Обновить'

Проверка результата и отладка

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

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

Как проверить, что передача работает

Параметры в ПриСозданииНаСервере
Норма

Параметры.Свойство() возвращает Истина, значение ожидаемого типа

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

Свойство отсутствует — проверьте имя ключа в структуре и что форма открывается именно этим вызовом

Возврат через ОповеститьОВыборе
Норма

Обработчик вызывается, Результат содержит выбранное значение

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

Обработчик не вызывается — нет Экспорт или форма открыта без ОписаниеОповещения

Временное хранилище
Норма

ПолучитьИзВременногоХранилища возвращает объект нужного типа

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

Возвращается Неопределено — не передан идентификатор формы или хранилище уже очищено

Оповестить между формами
Норма

ОбработкаОповещения срабатывает с нужным ИмяСобытия

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

Срабатывает в чужих формах или не срабатывает — проверьте уникальность и точное совпадение имени события

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

Как выбрать подходящий способ

Краткий маршрут выбора по типовым сценариям:

Маршрут решения

Как выбрать механизм

Нужно передать отбор, ссылку или пару простых значений в открываемую формуИспользуйте структуру параметров в ОткрытьФорму и чтение в ПриСозданииНаСервере
Нужно получить выбранное пользователем значение обратноОткрывайте форму с ОписаниеОповещения и возвращайте результат через ОповеститьОВыборе
Передаётся таблица значений, результат СКД или файлПоместите данные во временное хранилище с идентификатором формы и передайте адрес
Обе формы уже открыты и нужно уведомить о событииВызовите Оповестить с уникальным именем события и обработайте в ОбработкаОповещения
Нужно запретить повторное открытие той же формыПередайте ключ уникальности четвёртым параметром ОткрытьФорму
Итог

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

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

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

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

Технически можно обратиться к владельцу через свойство Владелец формы, но такой подход создаёт жёсткую связность: форма перестаёт работать, если её открыть из другого места. Правильнее возвращать результат через ОповеститьОВыборе или Оповестить — тогда форма не зависит от контекста вызова.

Почему параметры пустые в ПриСозданииНаСервере, хотя я их передавал?

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

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

Напрямую через параметры таблицу передавать не рекомендуется. Поместите её во временное хранилище методом ПоместитьВоВременноеХранилище с указанием УникальныйИдентификатор формы, передайте адрес строкой в параметрах, а в приёмнике извлеките через ПолучитьИзВременногоХранилища и загрузите в реквизит формы.

Чем ОповеститьОВыборе отличается от Оповестить?

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

Данные из временного хранилища пропадают — что делать?

Проверьте второй параметр ПоместитьВоВременноеХранилище: без идентификатора формы данные живут только до конца текущего серверного вызова. Передайте УникальныйИдентификатор формы, которая должна владеть данными. Также учтите, что после закрытия формы-владельца хранилище очищается.

Работают ли эти способы в обычных формах (толстый клиент)?

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