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

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

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

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

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

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

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

Что такое форма объекта и где она «живёт»

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

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

В обычном приложении форма работает в толстом клиенте и имеет более прямой доступ к объекту, поэтому код там проще, но сам режим считается устаревшим и встречается в основном в старых конфигурациях.

Как открыть форму объекта из кода

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

Открытие существующего объекта

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

ПараметрыФормы.Вставить("Ключ", СсылкаНаДокумент);

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

ПараметрыФормы);

Параметр «Ключ» указывает платформе, какой именно объект загрузить в форму. Если форма объекта назначена основной, можно использовать краткое имя "Документ.РеализацияТоваровУслуг.ФормаОбъекта" — платформа подставит форму по умолчанию.

Открытие формы нового объекта с заполнением

ЗначенияЗаполнения = Новый Структура;

ЗначенияЗаполнения.Вставить("Организация", ТекущаяОрганизация);

ЗначенияЗаполнения.Вставить("Контрагент", ВыбранныйКонтрагент);

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

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

ОткрытьФорму("Документ.ЗаказКлиента.ФормаОбъекта", ПараметрыФормы);

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

Порядок открытия формы объекта
  1. 1
    Определите полное имя формы: вид объекта + имя формы из конфигуратора
  2. 2
    Сформируйте структуру параметров: Ключ для существующего объекта или ЗначенияЗаполнения для нового
  3. 3
    Вызовите ОткрытьФорму() на клиенте
  4. 4
    Проверьте, что форма открылась с нужными данными и без ошибок прав доступа

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

Внутри модуля формы обращение идёт через несколько ключевых сущностей, которые часто путают:

  • ЭтаФорма — сама управляемая форма, через неё доступны все её свойства и методы;
  • Объект — основной реквизит формы с данными (например, Объект.Номер, Объект.Товары);
  • Элементы — коллекция элементов интерфейса (поля, кнопки, таблицы): Элементы.Товары.Видимость;
  • реквизиты формы — доступны напрямую по имени или через ЭтаФорма.ИмяРеквизита.
&НаКлиенте

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

// чтение данных объекта

ТекущийКонтрагент = Объект.Контрагент;

// изменение элемента интерфейса

Элементы.ГруппаДоставка.Видимость = Истина;

// обращение к реквизиту формы

ЭтаФорма.СчетчикИзменений = ЭтаФорма.СчетчикИзменений + 1;

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

Важно помнить про контекст выполнения. Код с директивой &НаКлиенте не может вызвать запросы к базе напрямую, а код &НаСервере не имеет доступа к элементам формы в части интерактивных действий. Для работы с данными на сервере реквизит «Объект» преобразуют в прикладной объект методом РеквизитФормыВЗначение("Объект"), а обратно — ЗначениеВРеквизитФормы().

Получение формы без открытия: ПолучитьФорму

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

ФормаДокумента = ПолучитьФорму("Документ.СчетНаОплатуПокупателю.Форма.ФормаДокумента",

Новый Структура("Ключ", СсылкаНаДокумент));

// вызов экспортной процедуры формы

ФормаДокумента.ПересчитатьИтоги();

// открытие формы на экране

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

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

ОткрытьФорму или ПолучитьФорму

ОткрытьФорму()

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

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

Нужна, когда требуется вызвать экспортные процедуры формы или заполнить её данные до показа. В управляемом режиме возможности ограничены.

Оповещения и владелец формы

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

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

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

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

Второй — оповещения. Метод Оповестить("ЗаписанДокумент", ПараметрыОповещения, Источник) рассылает сообщение всем формам, а заинтересованные формы обрабатывают его в ОбработкаОповещения. Для передачи результата в конкретную форму-источник применяют ОписаниеОповещения и метод ПоказатьВводЗначения/ОткрытьФорму с указанием обработчика.

&НаКлиенте

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

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

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

КонецЕсли;

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

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

Если нужно просто обновить список после записи документа, не пишите свой механизм оповещений — платформа сама рассылает стандартное оповещение при записи, и динамические списки обновляются автоматически. Ручная обработка нужна только для нестандартных сценариев.
ПЗ
Практическое замечание

Обращение к форме из модуля объекта и внешнего кода

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

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

&НаКлиенте

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

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

ОткрытьФорму("Документ.ПриходныйКассовыйОрдер.ФормаОбъекта",

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

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

Типичные ошибки и их диагностика

Большинство проблем при обращении к форме объекта сводятся к нескольким повторяющимся сценариям.

Типичные ошибки
01
Ошибка «Метод объекта не обнаружен» при вызове ПолучитьФорму на сервере — в управляемом приложении этот метод доступен только на клиенте
02
Обращение к Объект.Реквизит на клиенте с попыткой вызвать методы прикладного объекта — на клиенте доступна только структура данных, без методов вроде Записать()
03
Передача произвольного параметра в ОткрытьФорму без объявления его в параметрах формы — значение теряется или вызывает ошибку
04
Попытка найти открытую форму перебором окон — в управляемом приложении такого API нет, используйте оповещения
05
Изменение реквизита формы на клиенте и ожидание, что данные сохранились в базе — запись выполняется только явно через Записать() или серверный вызов

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

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

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

Открытие формы по ссылке
Норма

Форма открылась, поля заполнены данными объекта

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

Открылась пустая форма нового объекта — параметр Ключ не передан или ссылка пустая

Передача параметров
Норма

В ПриСозданииНаСервере параметр доступен через Параметры.ИмяПараметра

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

Параметр не объявлен в форме — значение недоступно

Запись из формы
Норма

После Записать() объект изменён в базе, список обновился

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

Данные изменились только на экране — запись не выполнялась

Часто задаваемые вопросы

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

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

Чем отличается Объект от ЭтаФорма в модуле формы?

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

Почему ПолучитьФорму выдаёт ошибку на сервере?

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

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

Передайте в ОткрытьФорму параметр РежимВыбора = Истина и ОписаниеОповещения с именем процедуры-обработчика. В форме выбора при выборе элемента платформа закроет форму и вызовет ваш обработчик, передав выбранное значение в параметре.

Как изменить данные объекта на сервере из формы?

В серверной процедуре формы преобразуйте реквизит в объект: Док = РеквизитФормыВЗначение("Объект"), измените свойства, вызовите Док.Записать(), затем при необходимости обновите форму через ЗначениеВРеквизитФормы(Док, "Объект").

Работает ли ОткрытьФорму в обычном приложении?

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

Итог

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

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