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