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

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

Модальность в 1С: что это и как работать с модальными окнами

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

Модальность в 1С — это способ взаимодействия программы с пользователем, при котором открытое окно блокирует работу со всеми остальными окнами приложения, пока пользователь не ответит на вопрос или не закроет диалог. Классический пример — сообщение «Сохранить изменения?» с кнопками «Да», «Нет» и «Отмена»: пока вы не нажмёте одну из них, продолжить работу невозможно.

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

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

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

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

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

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

Где встречается модальность на практике

Чаще всего разработчик сталкивается с модальностью в трёх местах. Первое — диалоги подтверждения: запись и проведение документа, отмена изменений, удаление объекта. В старых конфигурациях это вызовы Вопрос("Продолжить?", РежимДиалогаВопрос.ДаНет), в новых — ПоказатьВопрос() с описанием оповещения.

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

Третье — ввод простых значений: даты, числа, строки, пароля. Методы ВвестиЧисло(), ВвестиСтроку(), ВвестиДату() были модальными по своей природе. Их асинхронные аналоги — ПоказатьВводЧисла(), ПоказатьВводСтроки(), ПоказатьВводДаты().

Настройка режима использования модальности в конфигураторе

Режим модальности задаётся в свойствах конфигурации. Откройте дерево конфигурации, вызовите свойства корневого узла и найдите параметр «Режим использования модальности». Доступны три значения: «Использовать», «Не использовать» и «Использовать с предупреждениями».

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

Дополнительно есть свойство «Режим использования синхронных вызовов расширений платформы и внешних компонентов» — оно регулирует работу с файловой системой, криптографией и COM-объектами. Для веб-клиента его тоже нужно переводить в асинхронный режим.

Как найти модальные вызовы в коде

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

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

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

Как перевести конфигурацию на немодальный режим
  1. 1
    Сделайте копию базы и работайте только на ней
  2. 2
    Запустите проверку конфигурации с поиском модальных методов
  3. 3
    Замените каждый модальный вызов на асинхронный аналог с описанием оповещения
  4. 4
    Установите в свойствах конфигурации режим «Не использовать»
  5. 5
    Повторите проверку — список ошибок должен быть пустым
  6. 6
    Прогоните ключевые сценарии в тонком и веб-клиенте

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

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

Сравните два варианта. Старый модальный код:

Ответ = Вопрос("Провести документ?", РежимДиалогаВопрос.ДаНет);

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

ЗаписатьДокумент();

КонецЕсли;

Асинхронный эквивалент:

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

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

&НаКлиенте

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

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

ЗаписатьДокумент();

КонецЕсли;

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

Для форм вместо ОткрытьФормуМодально() используется ОткрытьФорму() с параметром «ОписаниеОповещенияОЗакрытии», а результат передаётся через Закрыть(ЗначениеРезультата) в открываемой форме. Важный нюанс: код после показа вопроса выполняется сразу, не дожидаясь ответа — всю логику, зависящую от ответа, нужно переносить в процедуру-обработчик.

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

Ограничения и когда модальность всё же допустима

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

Асинхронная модель имеет и свою цену. Код становится разорванным: одна логическая операция распределяется по нескольким процедурам, что усложняет чтение и отладку. Вложенные цепочки вопросов превращаются в «лесенку» оповещений. Для сложных сценариев приходится проектировать состояние формы заранее и передавать контекст через «ДополнительныеПараметры» описания оповещения.

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

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

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

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

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

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

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

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

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

Список содержит строки с Вопрос, Предупреждение, ОткрытьФормуМодально

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

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

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

Исключение «Использование модальных окон запрещено»

Логика после диалога
Норма

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

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

Код выполняется сразу, не дожидаясь ответа

Отмена в диалоге
Норма

Нажатие «Нет» или «Отмена» корректно прерывает операцию

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

Операция выполняется при любом ответе

Часто задаваемые вопросы

Чем модальное окно отличается от блокирующего окна владельца?

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

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

Браузерная среда не поддерживает синхронные модальные диалоги, поэтому платформа запрещает их в веб-клиенте независимо от настройки конфигурации. Ошибка означает, что в выполняемом коде есть вызов типа Вопрос(), Предупреждение() или ОткрытьФормуМодально(). Нужно найти этот вызов проверкой конфигурации и заменить на асинхронный аналог с описанием оповещения.

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

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

Что делать, если нужно задать пользователю несколько вопросов подряд?

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

Влияет ли отказ от модальности на обмены и фоновые задания?

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

Как открыть форму и получить из неё результат без ОткрытьФормуМодально?

Вызовите ОткрытьФорму() с параметром, содержащим описание оповещения о закрытии, либо назначьте обработчик через свойство формы. В открываемой форме в нужный момент вызовите Закрыть(Результат) — переданное значение придёт в обработчик закрытия как параметр результата. Альтернатива для простых случаев — методы ПоказатьВводЗначения и оповещение о выборе через ОповеститьОВыборе.

Итог

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

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