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

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

Как программно открыть общую форму в 1С

Как программно открыть общую форму в 1С 8.3: Метод ОткрытьФорму, ПолучитьФорму, передача параметров, обработка результата, типовые ошибки и примеры кода.

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

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

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

Что такое общая форма и где она создаётся

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

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

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

Открытие формы методом ОткрытьФорму

Основной способ в управляемом приложении — глобальный метод ОткрытьФорму(). Минимальный вызов выглядит так:

ОткрытьФорму("ОбщаяФорма.ФормаВыбораПериода");

Полный синтаксис включает до восьми параметров, все кроме первого необязательны:

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

"ОбщаяФорма.ФормаВыбораПериода", // имя формы

ПараметрыФормы, // структура параметров

ЭтотОбъект, // владелец формы

Новый УникальныйИдентификатор, // ключ уникальности

, // окно (необязательно)

, // навигационная ссылка

ОписаниеОповещения, // обработчик закрытия

РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

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

bsl
&НаКлиенте
Процедура ОткрытьНастройки(Команда)
	ПараметрыФормы = Новый Структура("Раздел", "ОбменДанными");
	ОткрытьФорму("ОбщаяФорма.НастройкиПрограммы", ПараметрыФормы, ЭтотОбъект);
КонецПроцедуры

Передача параметров в открываемую форму

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

// Код вызывающей стороны

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

ПараметрыФормы.Вставить("ДатаНачала", НачалоМесяца(ТекущаяДата()));

ПараметрыФормы.Вставить("ДатаОкончания", КонецМесяца(ТекущаяДата()));

ОткрытьФорму("ОбщаяФорма.ВыборПериода", ПараметрыФормы, ЭтотОбъект);

В модуле открываемой формы значения читаются в обработчике ПриСозданииНаСервере через коллекцию Параметры:

&НаСервере

Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)

Если Параметры.Свойство("ДатаНачала") Тогда

ДатаНачала = Параметры.ДатаНачала;

КонецЕсли;

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

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

Получение результата после закрытия формы

Чтобы узнать, что пользователь выбрал или ввёл в общей форме, передают описание оповещения — указатель на процедуру, которая выполнится после закрытия. Внутри общей формы результат возвращается методом Закрыть(Результат).

&НаКлиенте

Процедура ВыбратьПериод(Команда)

Оповещение = Новый ОписаниеОповещения("ПослеВыбораПериода", ЭтотОбъект);

ОткрытьФорму("ОбщаяФорма.ВыборПериода", , ЭтотОбъект, , , , Оповещение,

РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

&НаКлиенте

Процедура ПослеВыбораПериода(Результат, ДополнительныеПараметры) Экспорт

Если Результат = Неопределено Тогда

Возврат; // пользователь закрыл форму без выбора

КонецЕсли;

ДатаНачала = Результат.ДатаНачала;

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

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

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

Порядок действий для открытия с результатом
  1. 1
    Создайте общую форму и объявите нужные параметры в её свойствах
  2. 2
    В вызывающем модуле сформируйте структуру параметров и описание оповещения
  3. 3
    Вызовите ОткрытьФорму с указанием владельца и обработчика закрытия
  4. 4
    В общей форме верните результат через Закрыть(Результат)
  5. 5
    В обработчике оповещения проверьте Результат на Неопределено и обработайте данные

Модальный и блокирующий режимы открытия

Модальные вызовы (ОткрытьМодально()) в управляемом приложении запрещены по умолчанию: в конфигураторе стоит режим использования модальности «Не использовать», а веб-клиент модальность в принципе не поддерживает. Поэтому вместо модальности используют параметр РежимОткрытияОкнаФормы.

Доступные варианты поведения окна:

  • БлокироватьОкноВладельца — пользователь не может переключиться на форму-владельца, пока не закроет открытую; остальные окна приложения доступны;
  • БлокироватьВесьИнтерфейс — аналог модального окна: блокируется всё приложение;
  • Независимый — форма живёт своей жизнью и не закрывается вместе с владельцем.

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

Сравнение способов открытия

ОткрытьФорму с оповещением

Стандарт для управляемого приложения и веб-клиента. Асинхронно, работает везде, требует отдельной процедуры-обработчика.

ПолучитьФорму + ОткрытьМодально

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

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

Даёт доступ к объекту формы до открытия: можно заполнить реквизиты напрямую. Не рекомендуется в управляемом приложении из-за лишнего серверного вызова.

Метод ПолучитьФорму и когда он нужен

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

ФормаДиалога = ПолучитьФорму("ОбщаяФорма.Комментарий", , ЭтотОбъект);

ФормаДиалога.ТекстКомментария = ИсходныйТекст;

ФормаДиалога.Открыть();

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

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

Типовые ошибки и их устранение

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

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

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

Типичные ошибки
01
Чтение результата в строке после ОткрытьФорму — метод асинхронный, результат всегда будет пустым; нужен обработчик оповещения
02
Обработчик оповещения без Экспорт — платформа не находит процедуру, выбор пользователя теряется
03
Отсутствие проверки Результат = Неопределено — при закрытии формы крестиком логика выполняется с пустыми данными
04
Вызов ОткрытьФорму на сервере — ошибка выполнения, так как интерактивные действия доступны только на клиенте
05
Опечатка в имени формы или пропущенный префикс ОбщаяФорма. — исключение «Неизвестное имя формы»

Проверка результата и отладка

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

Для отладки удобно временно поставить точку останова в обработчике оповещения и посмотреть содержимое параметра «Результат» в табло. Если обработчик не вызывается вовсе, проверьте, что процедура экспортная, расположена в том же модуле, что и ЭтотОбъект из описания оповещения, и что форма-владелец не была закрыта раньше дочерней.

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

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

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

Форма открылась, параметры подставлены в поля

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

Ошибка «Неизвестное имя формы» или пустые поля

Возврат результата
Норма

Обработчик оповещения срабатывает, Результат содержит данные

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

Обработчик не вызывается или Результат = Неопределено при штатном выборе

Повторный вызов
Норма

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

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

Открываются дубликаты одного и того же диалога

Итог

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

В управляемом приложении общую форму открывают через ОткрытьФорму с указанием имени «ОбщаяФорма.Имя», параметров-структуры, владельца и описания оповещения. Результат получают только в обработчике закрытия с проверкой на Неопределено. Модальные вызовы заменяют режимом блокировки окна, а ПолучитьФорму оставляют для особых случаев.

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

Как открыть общую форму из формы списка документа?

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

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

Нет. Открытие форм — интерактивное действие, доступное только в клиентском контексте. Если условие показа формы вычисляется на сервере, верните признак на клиент и там вызовите ОткрытьФорму.

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

В управляемом приложении без модальности это невозможно: выполнение продолжается сразу. Перенесите продолжение логики в экспортную процедуру-обработчик оповещения. В обычном приложении или при разрешённой модальности можно использовать ОткрытьМодально, который вернёт значение напрямую.

Почему ОткрытьФорму выдаёт ошибку «Неизвестное имя формы»?

Проверьте, что форма существует в ветке «Общие формы», имя указано без опечаток и с префиксом «ОбщаяФорма.», а тип формы соответствует режиму запуска: управляемая форма не откроется в обычном приложении и наоборот.

Как передать в общую форму таблицу значений или массив?

Простые типы передаются в параметрах напрямую. Таблицу значений на клиенте нельзя создать, поэтому передавайте массив структур или ссылку на объект, а нужные данные общая форма получит на сервере в ПриСозданииНаСервере.

Чем отличается владелец формы от параметра «Окно»?

Владелец — это форма-родитель в логической иерархии: она получает оповещения и закрывает дочернюю форму при своём закрытии. Параметр «Окно» задаёт оконный контейнер интерфейса и влияет только на размещение окна на экране.