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