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

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

Как обратиться к реквизиту формы из другой формы в 1С

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

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

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

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

Почему нельзя обратиться к реквизиту формы напрямую

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

Поэтому конструкция вида Формы.ФормаДокумента.Реквизит1 не скомпилируется или не будет работать. Даже получив объект формы через ПолучитьФорму(), вы создадите новый экземпляр формы, а не получите доступ к уже открытой.

Передача данных через параметры при открытии формы

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

// В открывающей форме

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

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

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

ОткрытьФорму("Обработка.МояОбработка.Форма.ФормаНастроек", ПараметрыФормы, ЭтотОбъект);

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

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

Обращение к форме-владельцу через ВладелецФормы

Если форма открыта с указанием владельца (третий параметр ОткрытьФорму() или открытие из элемента формы), то внутри неё доступно свойство ВладелецФормы. Через него можно прочитать реквизиты и вызвать экспортные процедуры формы-родителя:

// В открываемой форме

&НаКлиенте

Процедура КомандаЗаполнить(Команда)

Если ВладелецФормы <> Неопределено Тогда

ВладелецФормы.Комментарий = "Заполнено из подчиненной формы";

ВладелецФормы.ОбновитьОтображениеДанных();

КонецЕсли;

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

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

Передача данных обратно через оповещения

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

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

&НаКлиенте

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

ОповеститьОВыборе(ВыбранноеЗначение);

// либо универсально:

Оповестить("ВыборКонтрагента", ВыбранноеЗначение, ЭтотОбъект);

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

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

&НаКлиенте

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

Если ИмяСобытия = "ВыборКонтрагента" Тогда

Контрагент = Параметр;

КонецЕсли;

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

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

Получение результата при закрытии формы

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

&НаКлиенте

Процедура ОткрытьНастройки(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияНастроек", ЭтотОбъект);

ОткрытьФорму("Обработка.МояОбработка.Форма.Настройки", , ЭтотОбъект, , , ,

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

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

&НаКлиенте

Процедура ПослеЗакрытияНастроек(Результат, ДопПараметры) Экспорт

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

ПериодОтчета = Результат.Период;

КонецЕсли;

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

Чтобы вернуть значение, в закрываемой форме вызывается Закрыть(СтруктураРезультата). Этот подход хорошо читается, не требует согласования имён событий и является стандартом для управляемого приложения.

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

Обмен между независимыми формами и хранение общих данных

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

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

&НаКлиенте

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

ФормаПриемник = ПолучитьФорму("Обработка.МояОбработка.Форма.РабочееМесто");

ФормаПриемник.УстановитьОтбор(Организация); // экспортная процедура

ФормаПриемник.Открыть();

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

Так работать можно, но помните: ПолучитьФорму() создаёт новый экземпляр, если форма не открыта. Вызов метода у уже открытой формы через повторный ПолучитьФорму() вернёт существующий экземпляр только при совпадении параметров уникальности.

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

Параметры при открытии

Подходит для передачи данных в новую форму. Ограничение: только на этапе создания, нельзя передать в уже открытую форму.

ВладелецФормы

Быстрый доступ к реквизитам формы-родителя. Ограничение: жёсткая связность и обязательная проверка на Неопределено.

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

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

ОписаниеОповещения при закрытии

Рекомендуемый способ получить результат выбора. Ограничение: срабатывает только при закрытии формы.

Экспортные методы формы

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

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

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

Вторая ошибка — обращение к реквизиту объекта через владельца без учёта контекста: ВладелецФормы.Номенклатура не сработает, если в форме-родителе данные лежат в основном реквизите Объект. Правильно: ВладелецФормы.Объект.Номенклатура.

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

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

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

После внедрения механизма проверьте сценарий целиком: откройте форму-источник, откройте из неё вторую форму, выполните передачу данных и убедитесь, что значение появилось в нужном реквизите и отобразилось в интерфейсе. Затем проверьте граничные случаи: открытие формы без владельца, закрытие без выбора значения (результат Неопределено), повторное открытие той же формы.

Для отладки удобно временно выводить передаваемые значения через Сообщить() или смотреть их в отладчике в точке останова внутри ОбработкаОповещения и ПриСозданииНаСервере. Если оповещение не приходит, первым делом проверьте совпадение строки имени события в отправителе и получателе — регистр и пробелы имеют значение.

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

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

Значение в форме-источнике
Норма

После выбора реквизит заполнен и виден в интерфейсе

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

Реквизит пуст или событие не сработало — проверьте имя оповещения

Открытие без владельца
Норма

Форма открывается без ошибки, обращение к ВладелецФормы обработано

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

Ошибка 'Поле объекта не обнаружено' — нет проверки на Неопределено

Закрытие без выбора
Норма

Обработчик получает Неопределено и ничего не меняет

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

Реквизит затирается пустым значением

Модифицированность
Норма

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

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

Изменения молча теряются

FAQ

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

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

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

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

Как передать в форму-владельца не одно значение, а несколько?

Соберите значения в структуру и передайте её как единый параметр: в Закрыть(Структура), в Оповестить как параметр события или присвойте несколько реквизитов владельца по очереди. Структура удобнее, так как обработчик получает всё одним объектом.

Почему ВладелецФормы равен Неопределено, хотя форму открыли из другой формы?

Владелец задаётся явно третьим параметром ОткрытьФорму() или наследуется, если форма открыта из элемента формы. Если ОткрытьФорму вызвана без указания владельца, свойство будет Неопределено. Передайте ЭтотОбъект третьим параметром.

Можно ли вызвать процедуру модуля другой формы?

Да, если процедура объявлена с директивой Экспорт и у вас есть ссылка на объект формы — через ВладелецФормы или результат ПолучитьФорму(). Учитывайте, что вызов серверной экспортной процедуры с клиента приведёт к серверному вызову.

Какой способ выбрать для формы подбора товаров в документ?

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

Итог

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

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