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

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

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

Что такое модальный диалог в 1С, чем отличается от немодального, почему модальные окна запрещены в веб-клиенте и как переписать код на асинхронные вызовы.

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

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

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

Как модальный диалог устроен и чем отличается от немодального

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

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

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

Какие методы 1С открывают модальные диалоги

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

Каждому синхронному методу соответствует асинхронная пара с префиксом «Показать» или «Начать»: ПоказатьВопрос, ПоказатьПредупреждение, ПоказатьВводЗначения, ПоказатьВводСтроки, НачатьПомещениеФайла, НачатьЗапускПриложения и другие. Первым параметром они принимают объект ОписаниеОповещения, в котором указано, какая процедура и с какими параметрами будет вызвана после завершения диалога.

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

Почему модальные вызовы запрещены в веб-клиенте

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

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

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

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

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

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

&НаКлиенте

Процедура УдалитьСтроки(Команда)

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

ПоказатьВопрос(Оповещение, "Удалить выбранные строки?",

РежимДиалогаВопрос.ДаНет, , КодВозвратаДиалога.Нет);

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

&НаКлиенте

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

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

УдалитьСтрокиНаСервере();

КонецЕсли;

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

Типичные ошибки при работе с модальными и асинхронными диалогами

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

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

Третья группа проблем — потеря контекста. Если обработчику нужны данные, которые были известны в момент показа вопроса (например, выбранная строка таблицы), их следует передать через третий параметр конструктора ОписаниеОповещения — дополнительные параметры. Рассчитывать на то, что состояние формы не изменится, пока пользователь думает над ответом, нельзя.

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

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

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

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

Маршрут решения

Как выбрать действие

Ошибка о запрете модальных окон возникает в типовой конфигурации после подключения внешней обработкиПроверьте код обработки на синхронные вызовы и перепишите их на асинхронные, режим конфигурации не меняйте
Конфигурация старая, на обычных формах, работает только в толстом клиентеМожно оставить режим «Использовать» и синхронные вызовы, но новые доработки лучше писать асинхронно
Планируется публикация через веб-сервер или мобильный клиентУстановите режим «Не использовать» и устраните все модальные вызовы по результатам проверки конфигурации
Нужно заблокировать интерфейс при открытии формы выбораИспользуйте ОткрытьФорму с ОписаниемОповещения и РежимОткрытияОкна.БлокироватьОкноВладельца
Итог

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

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

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

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

В 1С эти понятия близки, но не тождественны. Модальность — это свойство вызова остановить выполнение кода. Блокировка окна владельца — это свойство формы (РежимОткрытияОкна), которое запрещает взаимодействие с родительским окном, но не останавливает код. Асинхронная форма может блокировать интерфейс, оставаясь немодальной с точки зрения выполнения модуля.

Можно ли использовать модальные окна в тонком клиенте?

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

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

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

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

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

Как быстро найти все модальные вызовы в большой конфигурации?

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

Что делать, если модальный вызов находится в типовом коде, который нельзя менять?

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