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

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

Как определить тип формы в 1С: обычная или управляемая

Как определить тип формы в 1С: управляемая или обычная. Признаки в конфигураторе, программные способы через ТипЗнч, различия в модуле формы и типичные ошибки.

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

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

Почему вообще нужно различать типы форм

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

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

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

Как определить тип формы в конфигураторе по внешнему виду

Самый простой способ — открыть форму объекта в конфигураторе и посмотреть на структуру окна редактора формы. Управляемая и обычная формы выглядят принципиально по-разному.

У управляемой формы в левой части редактора находится дерево элементов формы и вкладки «Реквизиты», «Команды», «Параметры», «Командный интерфейс». Элементы добавляются перетаскиванием реквизитов в дерево, а не размещаются мышью на макете. Визуально редактор показывает структуру, а не точное расположение элементов — итоговый вид формирует платформа.

У обычной формы редактор выглядит как классический дизайнер: есть панель элементов управления (поле ввода, кнопка, табличное поле, надпись), элементы размещаются на форме мышью с точными координатами. Внизу окна — диалог с закладками «Диалог», «Модуль», «Реквизиты». Вкладок «Командный интерфейс» и «Команды» здесь нет.

Управляемая формаДерево элементов + реквизиты

Есть вкладки «Реквизиты», «Команды», «Командный интерфейс», элементы образуют иерархию, а не лежат на макете

Обычная формаДизайнер с координатами

Панель элементов управления, элементы размещаются мышью, есть разделители и привязки границ

Смешанный случайОба редактора доступны

У объекта могут существовать обе формы одновременно — проверяйте, какая назначена основной

Как определить тип формы по модулю

Модуль формы — второй надежный признак. Откройте модуль и посмотрите на директивы компиляции и структуру обработчиков.

В управляемой форме почти каждая процедура и функция помечена директивой: &НаКлиенте, &НаСервере, &НаСервереБезКонтекста, &НаКлиентеНаСервереБезКонтекста. Обработчики событий называются ПриСозданииНаСервере, ПриОткрытии, ПередЗаписьюНаСервере. Если вы видите такие директивы — форма управляемая.

В обычной форме директив компиляции нет вообще — весь модуль исполняется на клиенте. Обработчики называются иначе: ПриОткрытии, ПередЗаписью, ПриЗаписи — без суффиксов «НаСервере». Еще один признак: в обычной форме доступен объект ЭлементыФормы для обращения к элементам, тогда как в управляемой используется свойство Элементы.

Признаки в модуле формы

Управляемая форма

Директивы &НаКлиенте/&НаСервере, свойство Элементы, обработчики ПриСозданииНаСервере, реквизит Объект для форм объектов

Обычная форма

Без директив, коллекция ЭлементыФормы, обработчики ПриОткрытии и ПередЗаписью без суффиксов, прямой доступ к данным объекта

Программное определение типа формы в коде

Когда тип формы нужно определить во время выполнения — например, в общем модуле, который получает форму как параметр, — используются функции работы с типами.

Базовый вариант — проверка через ТипЗнч:

Если ТипЗнч(Форма) = Тип("УправляемаяФорма") Тогда

// работаем с управляемой формой

ИначеЕсли ТипЗнч(Форма) = Тип("Форма") Тогда

// обычная форма

КонецЕсли;

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

Альтернативный способ — проверка наличия характерных свойств. У управляемой формы есть свойство УникальныйИдентификатор и коллекция Элементы с элементами типа ПолеФормы, КнопкаФормы, ГруппаФормы. У обычной формы — коллекция ЭлементыФормы и свойство КлючУникальности.

1c
Функция ЭтоУправляемаяФорма(Форма) Экспорт
	Попытка
		Возврат ТипЗнч(Форма) = Тип("УправляемаяФорма");
	Исключение
		Возврат Ложь;
	КонецПопытки;
КонецФункции

Как определить режим приложения до создания формы

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

Для этого служит функция ТекущийРежимЗапуска(), которая возвращает значение системного перечисления: РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение или ОбычноеПриложение. Если приложение запущено в управляемом режиме — все формы, включая автоматически сгенерированные, будут управляемыми.

Если ТекущийРежимЗапуска() = РежимЗапускаКлиентскогоПриложения.УправляемоеПриложение Тогда

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

Иначе

ПолучитьФорму("Обработка.МояОбработка.Форма.ФормаОбычная").Открыть();

КонецЕсли;

Обратите внимание: толстый клиент может быть запущен в любом из двух режимов, поэтому проверка вида клиента (#Если ТолстыйКлиентОбычноеПриложение) не всегда равнозначна проверке режима запуска. Надежнее использовать именно ТекущийРежимЗапуска().

Маршрут решения

Как выбрать способ проверки

Форма уже открыта и передана в ваш код как параметрПроверяйте ТипЗнч(Форма) = Тип("УправляемаяФорма")
Форма еще не создана, нужно выбрать способ открытияИспользуйте ТекущийРежимЗапуска() и ветвите логику
Работаете в конфигураторе и сомневаетесь в типеОткройте редактор формы: дерево реквизитов — управляемая, дизайнер с координатами — обычная
Пишете внешнюю обработку для обоих режимовСоздайте две формы и выбирайте нужную по режиму запуска

Особенности внешних обработок и обоих типов форм у одного объекта

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

Для внешних обработок действует то же правило: можно создать две формы и в коде выбирать, какую открывать.

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

Типичные ошибки при определении типа формы

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

Вторая ошибка — использование модальных методов (ОткрытьМодально, Вопрос с модальным вызовом) в конфигурациях, где свойство «Режим использования модальности» установлено в «Не использовать». Это не связано с типом формы напрямую, но часто сопровождает переход на управляемые формы: модальные вызовы блокируются, и код молча не выполняется либо выдает ошибку.

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

Типичные ошибки
01
Обращение к ЭлементыФормы в управляемой форме — ошибка «Поле объекта не обнаружено» в момент выполнения, а не при компиляции
02
Проверка типа клиента вместо режима запуска — толстый клиент может работать в управляемом режиме, и логика сработает неверно
03
Открытие обычной формы в тонком клиенте — обычные формы там не поддерживаются, форма не откроется
04
Судить о типе формы по ее имени — имена у обоих типов одинаковые, признаком они не являются

Как проверить результат и перевести форму при необходимости

После того как вы определили тип формы и доработали код, проверьте результат в обоих режимах запуска, если конфигурация это допускает. В свойствах конфигурации параметр «Основной режим запуска» позволяет запустить отладку в нужном режиме, а параметр командной строки /RunModeOrdinaryApplication или /RunModeManagedApplication принудительно задает режим для конкретного сеанса.

Если требуется перевести обычную форму на управляемую, автоматического конвертера в платформе нет — форму создают заново: добавляют реквизиты, переносят элементы в дерево, переписывают обработчики с разделением на клиентские и серверные. Код, работающий с данными объекта, переносится в серверные процедуры, а интерфейсная логика остается на клиенте.

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

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

Форма открывается в целевом клиенте
Норма

Форма открылась без ошибок в тонком или толстом клиенте

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

Ошибка «Обычные формы не поддерживаются» или «Метод объекта не обнаружен»

Обращения к элементам формы
Норма

Код использует Элементы для управляемой и ЭлементыФормы для обычной

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

Смешение коллекций в одном коде без проверки типа формы

Универсальная обработка
Норма

В обоих режимах запуска открывается корректная форма

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

В одном из режимов форма не открывается или открывается автогенерированная

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

Как программно определить тип формы, если код выполняется на сервере?

На сервере управляемая форма существует как объект типа «УправляемаяФорма» внутри серверных процедур ее модуля — проверка ТипЗнч(ЭтаФорма) работает. Обычная форма на сервере не существует вовсе: весь ее код клиентский. Если ваш серверный общий модуль получил форму параметром, значит это точно управляемая форма.

Может ли у одного справочника быть две формы — обычная и управляемая?

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

Что вернет ТекущийРежимЗапуска() на сервере?

На сервере функция возвращает Неопределено, потому что режим запуска — характеристика клиентского сеанса, а не серверного вызова. Определяйте режим на клиенте и передавайте результат в серверные процедуры параметром, если он там нужен.

Почему форма открылась, но выглядит не так, как в конфигураторе?

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

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

Штатного конвертера в платформе нет. Форму пересоздают вручную: реквизиты и элементы добавляют заново, код разделяют на клиентские и серверные процедуры. Существуют сторонние инструменты миграции, но результат всегда требует ручной доработки и проверки.

Как понять, какой тип формы у внешней обработки, не открывая конфигуратор?

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

Итог

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

Тип формы определяется тремя способами: в конфигураторе — по виду редактора и директивам модуля, программно — через ТипЗнч(Форма) = Тип("УправляемаяФорма"), до создания формы — через ТекущийРежимЗапуска(). Обычные формы не работают в тонком и веб-клиенте, поэтому для универсального кода всегда ветвите логику по режиму запуска и никогда не судите о типе формы по ее имени.