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

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

1С: как обратиться к форме объекта и другим формам

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

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

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

Материал рассчитан на разработчиков и внедренцев, работающих с управляемыми формами в режиме управляемого приложения. Примеры кода приведены на встроенном языке 1С и применимы к типовым и самописным конфигурациям на платформе 8.3.

Основные способы обращения к форме в 1С

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

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

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

ОткрытьФорму: открытие формы для пользователя

Метод ОткрытьФорму() — стандартный способ показать форму пользователю. В простейшем виде вызов выглядит так: ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта"). Первый параметр — полное имя формы в формате «ВидОбъекта.ИмяОбъекта.ИмяФормы» или «ОбщаяФорма.ИмяФормы».

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

&НаКлиенте

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

ПараметрыФормы = Новый Структура("Ключ", ТекущаяСсылка);

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

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

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

Как открыть форму с параметрами
  1. 1
    Сформируйте структуру параметров: Новый Структура("Ключ", Ссылка)
  2. 2
    Вызовите ОткрытьФорму() с именем формы и структурой параметров
  3. 3
    При необходимости укажите владельца и ключ уникальности
  4. 4
    В открываемой форме обработайте параметры в событии ПриСозданииНаСервере через Параметры.Свойство()

ПолучитьФорму: программный доступ к данным формы

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

&НаКлиенте

Процедура ВыполнитьОбработку(Команда)

ФормаОбработки = ПолучитьФорму("Обработка.ЗагрузкаДанных.Форма");

ФормаОбработки.ПутьКФайлу = "C:\Data\import.xml";

ФормаОбработки.Открыть();

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

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

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

ЭтаФорма и ЭтотОбъект: обращение внутри модуля формы

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

Слово ЭтотОбъект в серверных процедурах формы объекта (документа, справочника) возвращает объект данных, который редактирует форма. Например, ЭтотОбъект.Записать() в модуле формы документа записывает документ. Это работает только в формах, у которых основной реквизит — данные объекта, и только на сервере.

Типичная путаница: разработчик пытается вызвать ЭтотОбъект в клиентской процедуре и получает ошибку. Данные объекта на клиенте доступны только через реквизит формы (обычно Объект), а методы объекта вроде Записать() требуют серверного контекста или использования ЭтаФорма.Записать(), которая сама выполнит серверный вызов.

КонструкцияГде доступнаЧто возвращает
ЭтаФормаМодуль формы, клиент и серверСама управляемая форма
ЭтотОбъектМодуль формы объекта, только серверДанные объекта (документ, справочник)
ОбъектМодуль формы, клиент и серверОсновной реквизит формы с данными
ВладелецФормыМодуль формы, клиентФорма-владелец, если задана при открытии

Как обратиться к одной форме из другой

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

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

&НаКлиенте

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

Если ИмяСобытия = "Запись_Номенклатура" Тогда

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

КонецЕсли;

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

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

Способы взаимодействия форм

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

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

Оповестить()

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

ОписаниеОповещения

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

ПолучитьФорму()

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

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

Параметры, переданные в ОткрытьФорму() или ПолучитьФорму(), доступны в открываемой форме через коллекцию Параметры в событии ПриСозданииНаСервере. Обращение выполняется через Параметры.ИмяПараметра или безопасно через Параметры.Свойство("ИмяПараметра", Значение), если параметр может отсутствовать.

&НаСервере

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

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

УстановитьОтбор(Параметры.ОтборПоОрганизации);

КонецЕсли;

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

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

После создания формы доступ к параметрам ограничен: коллекция Параметры очищается после ПриСозданииНаСервере. Если значения нужны позже, сохраните их в реквизиты формы в этом же обработчике.

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

Проверка результата и типичные ошибки

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

Если ПолучитьФорму() возвращает форму, но обращение к реквизиту даёт ошибку «Поле объекта не обнаружено», проверьте, существует ли реквизит с таким именем и не пытаетесь ли вы обратиться к реквизиту объекта, который не вынесен в реквизиты формы. Данные основного реквизита доступны через ФормаОбработки.Объект.ИмяРеквизита.

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

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

Форма открылась
Норма

Окно отображается, отборы и поля заполнены

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

Ошибка «Форма не найдена» — проверьте полное имя формы

Параметры переданы
Норма

В ПриСозданииНаСервере Параметры.Свойство() возвращает Истина

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

Параметр Неопределено — проверьте имя ключа в структуре

Обращение из другой формы
Норма

Экспортная клиентская процедура вызывается без ошибок

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

«Метод объекта не обнаружен» — процедура серверная или не экспортная

Повторное открытие
Норма

Активируется существующая форма

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

Открываются дубли — задайте ключ уникальности

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

Итог

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

ОткрытьФорму() — показать форму пользователю, ПолучитьФорму() — программный доступ к форме, ЭтаФорма — текущая форма изнутри, ЭтотОбъект — данные объекта на сервере. Между формами обменивайтесь через Оповестить, параметры читайте в ПриСозданииНаСервере, а работу с данными ведите через объектные методы, а не через формы.

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

Как обратиться к форме элемента справочника из внешней обработки?

Используйте ОткрытьФорму("Справочник.ИмяСправочника.ФормаОбъекта", Новый Структура("Ключ", СсылкаНаЭлемент)) из клиентской процедуры обработки. Если нужен программный доступ без отображения — замените на ПолучитьФорму() с теми же параметрами.

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

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

Почему ЭтотОбъект выдаёт ошибку в клиентской процедуре?

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

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

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

Чем отличается ОткрытьФормуМодально от ОткрытьФорму?

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

Как из общего модуля узнать, какая форма сейчас активна?

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