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