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