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

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

Модальные методы в 1С: что это и как их заменить

Разбираем, что такое модальные методы в 1С, почему их отключили, какие асинхронные аналоги использовать и как переписать старый код без ошибок.

Модальные методы в 1С — это методы встроенного языка, которые открывают диалоговое окно и приостанавливают выполнение кода до тех пор, пока пользователь не ответит: не нажмёт «ОК», «Отмена», не выберет файл или не введёт значение. Классические примеры — Вопрос(), Предупреждение(), ВвестиЗначение(), ВыбратьЭлемент() у списка справочника, а также диалоги выбора файлов.

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

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

Какие методы считаются модальными

К модальным относятся все методы, которые открывают окно и блокируют дальнейшее выполнение кода до закрытия этого окна. Наиболее распространённые:

  • Вопрос(ТекстВопроса, Кнопки) — возвращает код нажатой кнопки;
  • Предупреждение(Текст, Таймаут) — информационное окно;
  • ВвестиЗначение(Значение, Подсказка, Тип) — ввод произвольного значения;
  • ВвестиСтроку(), ВвестиЧисло(), ВвестиДату() — ввод конкретных типов;
  • ВыбратьЭлемент(), ВыбратьИзСписка() — выбор из списка;
  • методы диалогов работы с файлами: Выбрать() у ДиалогВыбораФайла, ПоместитьФайл() без асинхронного варианта;
  • ОткрытьЗначение() и модальное открытие форм через ОткрытьФормуМодально().

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

Почему платформа отказалась от модальности

Главная причина — веб-клиент. В браузере невозможно остановить выполнение JavaScript в ожидании действия пользователя: вся модель веб-приложений асинхронна. Чтобы одна и та же конфигурация работала в тонком, толстом и веб-клиенте без переписывания, платформа ввела единый асинхронный стиль.

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

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

Асинхронные аналоги модальных методов

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

Модальный методАсинхронная замена
Вопрос()ПоказатьВопрос(ОписаниеОповещения, Текст, Кнопки)
Предупреждение()ПоказатьПредупреждение(ОписаниеОповещения, Текст)
ВвестиЗначение()ПоказатьВводЗначения(ОписаниеОповещения, Значение, Подсказка)
ВвестиСтроку()ПоказатьВводСтроки()
ВыбратьИзСписка()ПоказатьВыборИзСписка()
ДиалогВыбораФайла.Выбрать()ДиалогВыбораФайла.Показать(ОписаниеОповещения)
ПоместитьФайл()НачатьПомещениеФайла()
ОткрытьФормуМодально()ОткрытьФорму() с обработчиком оповещения о закрытии

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

Как переписать модальный код на асинхронный

Типичный старый фрагмент выглядит так:

Ответ = Вопрос("Сохранить изменения?", РежимДиалогаВопрос.ДаНет);

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

СохранитьДанные();

КонецЕсли;

Асинхронный вариант требует двух процедур:

&НаКлиенте

Процедура ПередЗакрытиемОбработчик()

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

ПоказатьВопрос(Оповещение, "Сохранить изменения?", РежимДиалогаВопрос.ДаНет);

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

&НаКлиенте

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

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

СохранитьДанные();

КонецЕсли;

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

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

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

Блокирующие методы: почему их путают с модальными

Отдельная категория — блокирующие методы, которые не открывают окна, но приостанавливают выполнение, ожидая ответа системы: НайтиФайлы(), некоторые сетевые операции, методы работы с COM-объектами. В веб-клиенте и при определённых настройках они также недоступны.

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

Где модальность ещё допустима

Полный запрет касается клиентского кода в конфигурациях с режимом «Не использовать». В старых конфигурациях на поддержании, где режим модальности включён и работа идёт только в толстом или тонком клиенте, модальные методы продолжают функционировать. Также встречаются ситуации, когда форма открывается с РежимОткрытияОкна = БлокироватьОкноВладельца — это визуально «модальное» поведение, но реализованное без модальных методов, через обработчик ПриЗакрытии или оповещение о закрытии. Такой вариант полностью легален.

Типичные ошибки
01
Оставить код после асинхронного вызова в той же процедуре — он выполнится до ответа пользователя, логика сломается
02
Забыть слово Экспорт у процедуры-обработчика — платформа не сможет её вызвать
03
Перепутать порядок параметров обработчика: сначала Результат, потом ДополнительныеПараметры
04
Включить режим модальности «Использовать» вместо переписывания кода — конфигурация перестанет работать в веб-клиенте
05
Использовать Вопрос() в серверной процедуре — интерактивные методы доступны только на клиенте

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

Самый быстрый способ — установить свойство конфигурации «Режим использования модальности» в «Не использовать» и запустить проверку конфигурации (Конфигурация → Проверка конфигурации). Платформа укажет все места, где используются модальные и блокирующие методы. Дополнительно полезно прогнать ключевые сценарии вручную в веб-клиенте: некоторые проблемы проявляются только в рантайме.

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

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

Проверка конфигурации
Норма

Нет ошибок о модальных и блокирующих вызовах

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

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

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

Диалоги открываются, логика после ответа выполняется корректно

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

Исключение при вызове или код после диалога не срабатывает

Код после асинхронного вызова
Норма

Логика, зависящая от ответа, находится в процедуре-обработчике

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

Операторы стоят сразу после ПоказатьВопрос в той же процедуре

FAQ

Чем модальный метод отличается от асинхронного?

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

Можно ли использовать Вопрос() в новой конфигурации?

Нет, если режим использования модальности установлен в «Не использовать» — вызов завершится исключением. Вместо него применяйте ПоказатьВопрос() с описанием оповещения.

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

Через третий параметр конструктора: Новый ОписаниеОповещения("ИмяПроцедуры", ЭтотОбъект, МоиДанные). В обработчике эти данные будут доступны во втором параметре — ДополнительныеПараметры. Удобно передавать структуру с нужным контекстом.

Почему код после ПоказатьВопрос выполняется до ответа пользователя?

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

Что делать со старой конфигурацией, где много модальных вызовов?

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

Чем заменить ОткрытьФормуМодально()?

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