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