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