Разработка и Конфигурация · 13 мин
1С: как обратиться к форме объекта и другим формам
Как обратиться к форме в 1С: ПолучитьФорму, ОткрытьФорму, ЭтаФорма, ЭтотОбъект. Обращение к форме из другой формы, передача параметров, типовые ошибки.
Обращение к форме в 1С — одна из базовых задач при доработке конфигураций: нужно прочитать данные реквизитов формы, вызвать её процедуру, открыть форму другого объекта или получить текущую форму из общего модуля. Платформа 1С:Предприятие 8 предоставляет для этого несколько механизмов — ПолучитьФорму(), ОткрытьФорму(), свойства ЭтаФорма и ЭтотОбъект, а также оповещения для обмена данными между формами.
Выбор способа зависит от контекста: работаете ли вы в толстом или тонком клиенте, нужно ли просто открыть форму пользователю или программно обратиться к её данным, используется ли управляемое приложение или обычные формы. Неправильный выбор приводит к ошибкам вида «Объект не найден», падению клиентского приложения или неработающему коду на сервере.
Материал рассчитан на разработчиков и внедренцев, работающих с управляемыми формами в режиме управляемого приложения. Примеры кода приведены на встроенном языке 1С и применимы к типовым и самописным конфигурациям на платформе 8.3.
Основные способы обращения к форме в 1С
В управляемом приложении 1С существует четыре основных сценария обращения к форме. Первый — открытие формы для пользователя через ОткрытьФорму(): платформа создаёт форму, показывает её в интерфейсе и возвращает управление. Второй — программное получение формы через ПолучитьФорму(): форма создаётся в памяти, но не отображается, пока вы явно не вызовете метод Открыть().
Третий сценарий — обращение к текущей форме из её собственного модуля через ключевое слово ЭтаФорма. Четвёртый — обращение к данным объекта, который редактирует форма, через ЭтотОбъект в серверных процедурах формы. Путаница между этими сценариями — самая частая причина ошибок у начинающих разработчиков.
Важно понимать: оба метода — ОткрытьФорму() и ПолучитьФорму() — доступны только на клиенте. На сервере получить или открыть форму нельзя, потому что форма — это клиентский интерфейсный объект. Если нужно обработать данные на сервере, передайте туда параметры или ссылку на объект, а не форму.
ОткрытьФорму: открытие формы для пользователя
Метод ОткрытьФорму() — стандартный способ показать форму пользователю. В простейшем виде вызов выглядит так: ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта"). Первый параметр — полное имя формы в формате «ВидОбъекта.ИмяОбъекта.ИмяФормы» или «ОбщаяФорма.ИмяФормы».
Для открытия формы конкретного объекта передайте параметр Ключ со ссылкой. Параметры передаются через структуру:
&НаКлиенте
Процедура ОткрытьКарточку(Команда)
ПараметрыФормы = Новый Структура("Ключ", ТекущаяСсылка);
ОткрытьФорму("Справочник.Номенклатура.ФормаОбъекта", ПараметрыФормы);
КонецПроцедуры
Дополнительные параметры метода позволяют указать владельца формы, уникальность, окно и режим открытия. Если передать владельца, форма будет закрываться вместе с ним и станет доступна через свойство ВладелецФормы — это удобно для подчинённых окон выбора. Параметр Уникальность предотвращает открытие нескольких копий одной и той же формы: при повторном вызове с тем же ключом уникальности активируется уже открытая форма.
- 1Сформируйте структуру параметров: Новый Структура("Ключ", Ссылка)
- 2Вызовите ОткрытьФорму() с именем формы и структурой параметров
- 3При необходимости укажите владельца и ключ уникальности
- 4В открываемой форме обработайте параметры в событии ПриСозданииНаСервере через Параметры.Свойство()
ПолучитьФорму: программный доступ к данным формы
Метод ПолучитьФорму() создаёт форму в памяти без отображения и возвращает на неё ссылку. Через эту ссылку можно обращаться к реквизитам формы, экспортным процедурам и функциям её модуля. Типичный пример — получение формы обработки для выполнения служебной операции:
&НаКлиенте
Процедура ВыполнитьОбработку(Команда)
ФормаОбработки = ПолучитьФорму("Обработка.ЗагрузкаДанных.Форма");
ФормаОбработки.ПутьКФайлу = "C:\Data\import.xml";
ФормаОбработки.Открыть();
КонецПроцедуры
Ограничение важно учитывать: обращаться к экспортным процедурам модуля формы можно только к тем, которые объявлены с директивой &НаКлиенте, потому что вызов идёт с клиента. Серверные процедуры формы извне напрямую вызвать нельзя — это архитектурное ограничение платформы.
Каждый вызов ПолучитьФорму() без параметра уникальности создаёт новый экземпляр формы. Если нужно повторно использовать уже созданную форму, передайте одинаковый ключ уникальности — платформа вернёт существующий экземпляр. Это также защищает от утечек памяти при многократных вызовах.
ЭтаФорма и ЭтотОбъект: обращение внутри модуля формы
Внутри модуля формы ключевое слово ЭтаФорма ссылается на саму форму и позволяет обращаться к её реквизитам, элементам и свойствам: ЭтаФорма.Закрыть(), ЭтаФорма.Элементы.ТаблицаТоваров.Видимость = Ложь. В клиентских процедурах имя ЭтаФорма можно опускать — реквизиты и элементы доступны напрямую по имени.
Слово ЭтотОбъект в серверных процедурах формы объекта (документа, справочника) возвращает объект данных, который редактирует форма. Например, ЭтотОбъект.Записать() в модуле формы документа записывает документ. Это работает только в формах, у которых основной реквизит — данные объекта, и только на сервере.
Типичная путаница: разработчик пытается вызвать ЭтотОбъект в клиентской процедуре и получает ошибку. Данные объекта на клиенте доступны только через реквизит формы (обычно Объект), а методы объекта вроде Записать() требуют серверного контекста или использования ЭтаФорма.Записать(), которая сама выполнит серверный вызов.
| Конструкция | Где доступна | Что возвращает |
|---|---|---|
| ЭтаФорма | Модуль формы, клиент и сервер | Сама управляемая форма |
| ЭтотОбъект | Модуль формы объекта, только сервер | Данные объекта (документ, справочник) |
| Объект | Модуль формы, клиент и сервер | Основной реквизит формы с данными |
| ВладелецФормы | Модуль формы, клиент | Форма-владелец, если задана при открытии |
Как обратиться к одной форме из другой
Прямое обращение из одной открытой формы к другой технически возможно, если у вас есть ссылка на форму — например, вы сохранили результат ПолучитьФорму() в переменной или открыли форму с указанием владельца. Из дочерней формы владелец доступен через ЭтаФорма.ВладелецФормы, и можно вызвать его экспортные клиентские процедуры или прочитать реквизиты.
Однако рекомендуемый механизм обмена данными между формами — оповещения. Форма-источник вызывает Оповестить("ИмяСобытия", Параметр, Источник), а форма-приёмник обрабатывает событие в ОбработкаОповещения. Это слабая связь: формы не зависят от существования друг друга, и код не сломается, если приёмник закрыт.
&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
Если ИмяСобытия = "Запись_Номенклатура" Тогда
ЭтаФорма.ОбновитьОтображениеДанных();
КонецЕсли;
КонецПроцедуры
Для возврата результата из модально открытой формы используйте ОповеститьОВыборе() или механизм обработчиков ожидания с ОписаниеОповещения при открытии через ОткрытьФорму() с указанием описания оповещения о закрытии. Это стандартный способ получить выбранное значение из формы подбора.
Способы взаимодействия форм
Подходит для подчинённых форм выбора. Ограничение: жёсткая связь, работает только пока обе формы открыты.
Универсальный обмен событиями между любыми формами. Ограничение: нет гарантии, что приёмник существует.
Возврат результата при закрытии формы. Ограничение: только один обработчик на открытие.
Программный доступ к реквизитам и процедурам формы. Ограничение: только клиентские экспортные методы.
Передача параметров и обработка в открываемой форме
Параметры, переданные в ОткрытьФорму() или ПолучитьФорму(), доступны в открываемой форме через коллекцию Параметры в событии ПриСозданииНаСервере. Обращение выполняется через Параметры.ИмяПараметра или безопасно через Параметры.Свойство("ИмяПараметра", Значение), если параметр может отсутствовать.
&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка, Параметры)
Если Параметры.Свойство("ОтборПоОрганизации") Тогда
УстановитьОтбор(Параметры.ОтборПоОрганизации);
КонецЕсли;
КонецПроцедуры
Учтите: чтобы параметр был доступен в форме, он должен быть объявлен в редакторе формы на закладке «Параметры», либо обращение идёт как к произвольному параметру через Свойство(). Ключевые параметры с установленным признаком «Ключевой» влияют на уникальность формы — формы с разными значениями ключевых параметров считаются разными.
После создания формы доступ к параметрам ограничен: коллекция Параметры очищается после ПриСозданииНаСервере. Если значения нужны позже, сохраните их в реквизиты формы в этом же обработчике.
Проверка результата и типичные ошибки
Признак корректного открытия формы — она появилась в интерфейсе, параметры применились (отборы установлены, поля заполнены), а в ПриСозданииНаСервере не возникло исключений. Если форма не открывается, первым делом проверьте правильность полного имени формы: ошибка в строке имени — самая частая причина сообщения «Форма не найдена».
Если ПолучитьФорму() возвращает форму, но обращение к реквизиту даёт ошибку «Поле объекта не обнаружено», проверьте, существует ли реквизит с таким именем и не пытаетесь ли вы обратиться к реквизиту объекта, который не вынесен в реквизиты формы. Данные основного реквизита доступны через ФормаОбработки.Объект.ИмяРеквизита.
Как проверить результат
Окно отображается, отборы и поля заполнены
Ошибка «Форма не найдена» — проверьте полное имя формы
В ПриСозданииНаСервере Параметры.Свойство() возвращает Истина
Параметр Неопределено — проверьте имя ключа в структуре
Экспортная клиентская процедура вызывается без ошибок
«Метод объекта не обнаружен» — процедура серверная или не экспортная
Активируется существующая форма
Открываются дубли — задайте ключ уникальности
Для отладки используйте конфигуратор: поставьте точку останова в ПриСозданииНаСервере открываемой формы и проверьте содержимое коллекции Параметры через табло. Это быстрее, чем гадать, почему форма ведёт себя не так, как ожидалось.
Что важно запомнить
ОткрытьФорму() — показать форму пользователю, ПолучитьФорму() — программный доступ к форме, ЭтаФорма — текущая форма изнутри, ЭтотОбъект — данные объекта на сервере. Между формами обменивайтесь через Оповестить, параметры читайте в ПриСозданииНаСервере, а работу с данными ведите через объектные методы, а не через формы.
Частые вопросы
Как обратиться к форме элемента справочника из внешней обработки?
Используйте ОткрытьФорму("Справочник.ИмяСправочника.ФормаОбъекта", Новый Структура("Ключ", СсылкаНаЭлемент)) из клиентской процедуры обработки. Если нужен программный доступ без отображения — замените на ПолучитьФорму() с теми же параметрами.
Можно ли получить уже открытую форму, не создавая новую?
Да, если при первом получении или открытии вы задали ключ уникальности. Повторный вызов ПолучитьФорму() с тем же ключом вернёт существующий экземпляр. Без ключа уникальности платформа каждый раз создаёт новую форму.
Почему ЭтотОбъект выдаёт ошибку в клиентской процедуре?
ЭтотОбъект доступен только в серверном контексте модуля формы объекта. На клиенте работайте с данными через реквизит формы Объект, а для записи используйте ЭтаФорма.Записать().
Как передать таблицу значений в открываемую форму?
Напрямую через параметры таблицу значений передать нельзя — параметры сериализуются. Варианты: передать массив структур, поместить таблицу во временное хранилище через ПоместитьВоВременноеХранилище() и передать адрес, либо заполнить таблицу в приёмнике запросом по переданным отборам.
Чем отличается ОткрытьФормуМодально от ОткрытьФорму?
Модальное открытие блокирует родительское окно до закрытия формы. В современных конфигурациях режим модальности часто запрещён настройками, поэтому вместо ОткрытьФормуМодально() рекомендуется использовать ОткрытьФорму() с ОписаниеОповещения для обработки результата после закрытия.
Как из общего модуля узнать, какая форма сейчас активна?
Стандартного надёжного способа получить активную форму из произвольного общего модуля нет — архитектура управляемого приложения это намеренно ограничивает. Передавайте ссылку на форму (ЭтаФорма) параметром в вызываемую процедуру общего модуля, если общий модуль клиентский.