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

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

Как вывести модальное окно в 1С

Как вывести модальное окно в 1С 8.3: методы ПоказатьВопрос, ПоказатьПредупреждение, ОткрытьФормуМодально, блокирующие окна и примеры кода с пояснениями.

Модальное окно в 1С — это диалог, который блокирует работу с остальным интерфейсом до тех пор, пока пользователь не ответит или не закроет его. Такие окна применяются для подтверждения удаления, предупреждений о незаполненных реквизитах, выбора варианта действия и ввода простых значений.

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

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

Какие виды модальных окон есть в 1С

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

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

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

ПоказатьПредупреждение

Информационное сообщение с кнопкой ОК. Асинхронный, работает везде, включая веб-клиент.

ПоказатьВопрос

Подтверждение действия с кнопками Да/Нет и другими. Асинхронный, результат приходит в оповещение.

Вопрос() / Предупреждение()

Синхронные методы. Требуют включённой модальности, не работают в веб-клиенте.

ОткрытьФормуМодально

Открытие произвольной формы с блокировкой. Устаревший, заменяется на ОткрытьФорму с РежимОткрытияОкна.БлокироватьОкноВладельца.

Асинхронный вывод вопроса через ПоказатьВопрос

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

&НаКлиенте

Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)

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

ПоказатьВопрос(Оповещение, "Записать документ?",

РежимДиалогаВопрос.ДаНет, 20, КодВозвратаДиалога.Нет);

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

&НаКлиенте

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

Если Результат = КодВозвратаДиалога.Да Тогда

Записать();

КонецЕсли;

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

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

Информационное окно и ввод значения

Для простого сообщения используется ПоказатьПредупреждение. Если реакция на закрытие не нужна, первый параметр можно не передавать или указать Неопределено. Параметр «Таймаут» задаёт время в секундах, после которого окно закроется само.

Для запроса значения — ПоказатьВводЗначения, ПоказатьВводЧисла, ПоказатьВводСтроки или ПоказатьВводДаты. Они открывают окно с полем ввода и кнопками ОК/Отмена; если пользователь нажал «Отмена», в обработчик приходит Неопределено, и это нужно проверять.

&НаКлиенте

Процедура ВвестиКоличество(Команда)

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

ПоказатьВводЧисла(Оповещение, 1, "Введите количество", 10, 2);

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

&НаКлиенте

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

Если Число = Неопределено Тогда

Возврат; // пользователь отменил ввод

КонецЕсли;

Количество = Число;

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

Открытие формы в блокирующем режиме

Когда стандартных диалогов недостаточно, открывают собственную форму. Современный способ — метод ОткрытьФорму с параметром РежимОткрытияОкна, установленным в БлокироватьОкноВладельца или БлокироватьВесьИнтерфейс. Результат возвращается через описание оповещения, а форма закрывается методом Закрыть(Результат).

&НаКлиенте

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

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

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , ,

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

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

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

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

Настройка модальности в конфигурации

Если требуется поддерживать старый код с синхронными вызовами, в свойствах конфигурации есть параметр «Режим использования модальности». Значение «Использовать» разрешает модальные вызовы, «Не использовать» запрещает их, и тогда Вопрос() вызовет исключение. В типовых конфигурациях режим обычно отключён.

Даже при включённой модальности веб-клиент и мобильная платформа синхронные диалоги не поддерживают. Поэтому включать режим имеет смысл только как временную меру на период постепенного рефакторинга, а не как постоянное решение.

Типичные ошибки и их диагностика

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

Вторая группа ошибок — логические: разработчик ожидает, что код после ПоказатьВопрос выполнится после ответа, хотя на самом деле он выполняется сразу. Характерный симптом — документ записывается даже при нажатии «Нет». Лечится переносом зависимой логики в обработчик.

Типичные ошибки
01
Вызов ПоказатьВопрос в серверной процедуре — компилятор выдаст ошибку, диалоги доступны только на клиенте
02
Обработчик оповещения без Экспорт — платформа не найдёт процедуру, ответ потеряется
03
Код после ПоказатьВопрос рассчитан на ответ — он выполнится раньше, чем пользователь нажмёт кнопку
04
Отсутствие проверки на Неопределено после ввода значения — при отмене в переменную попадёт некорректное значение
05
Использование ОткрытьФормуМодально в конфигурации с запрещённой модальностью — исключение в момент вызова

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

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

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

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

Нажатие основной кнопки (Да/ОК)
Норма

Выполняется целевое действие — запись, удаление, выбор

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

Ничего не происходит или действие выполняется дважды

Нажатие Отмена/Нет
Норма

Действие отменяется, данные не меняются

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

Действие выполняется несмотря на отказ

Работа в веб-клиенте
Норма

Окно открывается и блокирует интерфейс

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

Ошибка о недопустимости модального вызова

Итог

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

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

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

Почему ПоказатьВопрос вызывает ошибку «Использование модальных окон запрещено»?

Эта ошибка относится к синхронному методу Вопрос(), а не к ПоказатьВопрос. Если она появляется, в коде где-то остался старый вызов. Найдите его глобальным поиском по модулю и замените на асинхронный вариант с описанием оповещения.

Как передать в обработчик оповещения свои данные?

Третьим параметром конструктора Новый ОписаниеОповещения передайте произвольное значение — обычно структуру. В обработчике оно придёт вторым параметром (ДополнительныеПараметры). Так удобно передавать, например, ссылку на документ или идентификатор строки таблицы.

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

Нет. Диалоги доступны только в клиентском контексте. Если решение принимается на сервере, верните признак на клиент и уже там вызовите ПоказатьВопрос. Либо используйте директиву &НаКлиентеНаСервереБезКонтекста с проверкой, но сам вызов диалога всё равно должен быть в клиентской ветке.

Как сделать, чтобы окно закрылось само через несколько секунд?

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

Чем заменить ОткрытьФормуМодально для формы выбора?

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

Работают ли модальные окна в мобильном клиенте?

Асинхронные методы (ПоказатьВопрос, ПоказатьПредупреждение) в мобильной платформе поддерживаются. Синхронные модальные вызовы — нет. Поэтому при разработке под мобильный клиент асинхронный подход является единственным вариантом.