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