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