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

Программист 1С v8.3 (Управляемые формы) IT и автоматизация бизнеса
← На главную

При переходе на новые версии платформы 1С:Предприятие 8.3 (начиная с релиза 8.3.10) разработчики и администраторы часто сталкиваются с ситуацией, когда конфигурация отлично работает в тонком клиенте, но при запуске через веб-клиент в любом интернет-браузере падает с ошибкой: «Использование модальных окон в данном режиме запрещено». При этом свойство конфигурации Режим использования модальности установлено в значение Использовать.

Разберем подробнее, почему так происходит, какие архитектурные изменения лежат в основе этого поведения и как правильно переписать код для стабильной работы веб-клиента.

Причины возникновения ошибки в веб-клиенте

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

По этой причине, начиная с релиза 8.3.10, в платформе 1С:Предприятие полностью прекращена поддержка модальных окон при работе в веб-клиенте. Это ограничение действует на уровне движка платформы и игнорирует настройку Режим использования модальности = Использовать в свойствах конфигурации. Если в коде вызывается любой модальный метод, веб-клиент незамедлительно генерирует исключительную ситуацию.

Способ 1. Замена модальных методов на вызовы с использованием ОписаниеОповещения

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

Сопоставим основные модальные методы и их немодальные аналоги:

  1. Вопрос(...) заменяется на ПоказатьВопрос(...)
  2. Предупреждение(...) заменяется на ПоказатьПредупреждение(...)
  3. ВвестиЗначение(...) заменяется на ПоказатьВводЗначения(...)
  4. ВвестиСтроку(...) заменяется на ПоказатьВводСтроки(...)
  5. ВвестиЧисло(...) заменяется на ПоказатьВводЧисла(...)
  6. ВвестиДату(...) заменяется на ПоказатьВводДаты(...)
  7. ОткрытьФормуМодально(...) заменяется на ОткрытьФорму(...)

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


&НаКлиенте
Процедура УдалитьЗаписьМодально()
	Ответ = Вопрос("Удалить выбранный элемент?", РежимДиалогаВопрос.ДаНет);
	Если Ответ = КодВозвратаДиалога.Да Тогда
		ВыполнитьУдаление();
	КонецЕсли;
КонецПроцедуры

Перепишем этот фрагмент с использованием объекта ОписаниеОповещения:


&НаКлиенте
Процедура УдалитьЗапись()
	Оповещение = Новый ОписаниеОповещения("УдалитьЗаписьЗавершение", ЭтотОбъект);
	ПоказатьВопрос(Оповещение, "Удалить выбранный элемент?", РежимДиалогаВопрос.ДаНет);
КонецПроцедуры

&НаКлиенте
Процедура УдалитьЗаписьЗавершение(РезультатВопроса, ДополнительныеПараметры) Экспорт
	Если РезультатВопроса = КодВозвратаДиалога.Да Тогда
		ВыполнитьУдаление();
	КонецЕсли;
КонецПроцедуры

Способ 2. Использование современного асинхронного синтаксиса (Асинх / Ждать)

Если разработка ведется на платформе версии 8.3.18 и выше, мы можем использовать механизм асинхронных процедур и функций. Это позволяет сохранить линейную и легко читаемую структуру кода без создания вспомогательных процедур обратного вызова.

Для этого процедура объявляется с ключевым словом Асинх, а перед вызовом асинхронного метода (с суффиксом ...Асинх) указывается оператор Ждать.

Посмотрим на пример реализации того же диалога:


&НаКлиенте
Асинх Процедура УдалитьЗаписьАсинхронно()
	Ответ = Ждать ВопросАсинх("Удалить выбранный элемент?", РежимДиалогаВопрос.ДаНет);
	Если Ответ = КодВозвратаДиалога.Да Тогда
		ВыполнитьУдаление();
	КонецЕсли;
КонецПроцедуры

Аналогично работают методы ПредупреждениеАсинх, ВвестиЗначениеАсинх, ВвестиСтрокуАсинх, ВвестиЧислоАсинх и ВвестиДатуАсинх.

Способ 3. Эмуляция модальности при открытии форм

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

Существуют два режима блокировки:

  1. РежимОткрытияОкнаФормы.БлокироватьОкноВладельца — блокирует родительское окно, из которого была открыта форма.
  2. РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс — полностью блокирует интерфейс программы для пользователя.

Рассмотрим пример открытия формы выбора с блокировкой родительской формы и обработкой результата:


&НаКлиенте
Процедура ВыбратьНоменклатуру()
	ОповещениеОЗакрытии = Новый ОписаниеОповещения("ОбработатьВыборНоменклатуры", ЭтотОбъект);
	ПараметрыФормы = Новый Структура("ЗакрыватьПриВыборе", Истина);
	
	ОткрытьФорму(
		"Справочник.Номенклатура.ФормаВыбора",
		ПараметрыФормы,
		ЭтотОбъект,
		,
		,
		,
		ОповещениеОЗакрытии,
		РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
	);
КонецПроцедуры

&НаКлиенте
Процедура ОбработатьВыборНоменклатуры(ЗначениеВыбора, ДополнительныеПараметры) Экспорт
	Если ЗначениеВыбора <> Неопределено Тогда
		Объект.Номенклатура = ЗначениеВыбора;
	КонецЕсли;
КонецПроцедуры

Инструменты поиска и рефакторинга модальных вызовов в Конфигураторе

Чтобы быстро найти все проблемные места в конфигурации, воспользуемся встроенными механизмами проверки:

  1. Откроем главное меню: Конфигурация → Проверка конфигурации.
  2. В списке проверок включим флаг «Поиск некорректных вызовов модальных методов».
  3. Нажмем кнопку «Выполнить» и получим список процедур, требующих переработки.
  4. Для части стандартных методов можно применить автоматизированный рефакторинг платформы, выбрав соответствующий пункт в контекстном меню модуля.
  5. В свойствах корневого узла конфигурации рекомендуется перевести свойство Режим использования модальности в значение Не использовать или Использовать с предупреждениями, чтобы выявлять модальные вызовы на раннем этапе тестирования даже в тонком клиенте.

Временное решение без изменения конфигурации

Если конфигурация находится на поддержке или содержит большое количество модальных окон, а оперативно внести изменения в код невозможно, единственным временным решением является перевод пользователей с веб-браузера на тонкий клиент 1С:Предприятия.

Тонкий клиент способен подключаться к базе через веб-сервер по протоколам HTTP/HTTPS так же, как и браузер, однако при установленном режиме конфигурации Режим использования модальности = Использовать модальные окна в нем продолжают функционировать.

← На главную