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