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

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

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

Разбираем, как открыть модальное окно в 1С: ОткрытьФормуМодально, ПоказатьВопрос, ПоказатьВводЗначения, режимы блокировки, ошибки и примеры кода для разработчика.

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

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

Ниже разобраны основные способы открыть модальное окно: от простого диалога с кнопками «Да/Нет» до открытия собственной формы с блокировкой владельца. Примеры приведены на встроенном языке 1С и подходят для управляемых форм типовых и самописных конфигураций.

Что считается модальным окном в 1С и когда оно нужно

Модальным называется окно, которое захватывает фокус и не даёт взаимодействовать с родительской формой, пока пользователь не завершит действие. В 1С это может быть системный диалог (вопрос, предупреждение, ввод значения) или обычная форма объекта, открытая с блокировкой окна владельца или всего интерфейса.

Типичные сценарии, где модальное поведение оправдано: подтверждение удаления или проведения документа, ввод причины отказа, выбор одного значения перед продолжением операции, предупреждение о потере несохранённых данных. Во всех этих случаях логика программы не должна продолжаться, пока пользователь не ответит.

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

Как открыть диалог с вопросом через ПоказатьВопрос

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

&НаКлиенте

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

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

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

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

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

&НаКлиенте

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

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

// выполняем удаление

КонецЕсли;

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

Обратите внимание на параметры: таймаут в секундах (после него возвращается значение по умолчанию) и кнопку по умолчанию. Для деструктивных действий кнопкой по умолчанию делайте безопасный вариант — «Нет» или «Отмена», чтобы случайное нажатие Enter не привело к потере данных.

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

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

Как открыть окно ввода значения

Когда требуется получить от пользователя одно значение — строку, число, дату или ссылку на объект базы — используется ПоказатьВводЗначения(). Метод открывает модальное окно с полем ввода заданного типа и кнопками подтверждения и отмены.

&НаКлиенте

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

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

ПоказатьВводЗначения(Оповещение, "", "Укажите причину отмены", "Строка");

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

&НаКлиенте

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

Если Значение <> Неопределено Тогда

// значение введено, продолжаем

КонецЕсли;

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

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

Для ввода ссылки на объект базы вместо строки с типом передайте описание типов: Новый ОписаниеТипов("СправочникСсылка.Номенклатура") — тогда в окне появится поле выбора с кнопкой открытия списка.

Как открыть форму объекта в модальном режиме

Чтобы открыть собственную форму (например, форму элемента справочника или произвольную форму обработки) с блокировкой родительского окна, используйте ОткрытьФорму() с явным указанием режима открытия окна.

&НаКлиенте

Процедура ОткрытьНастройки(Команда)

ПараметрыФормы = Новый Структура("РежимВыбора", Истина);

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

ОткрытьФорму("Обработка.НастройкиОбмена.Форма.ФормаНастроек",

ПараметрыФормы, ЭтотОбъект, , , , Оповещение,

РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);

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

Доступны два основных режима блокировки: БлокироватьОкноВладельца — блокируется только форма, из которой открыли новое окно, и БлокироватьВесьИнтерфейс — блокируется всё приложение. Второй вариант применяйте редко, например при критичной настройке, без которой дальнейшая работа невозможна.

Чтобы вернуть результат из модальной формы обратно, внутри неё вызовите Закрыть(Результат) — переданное значение придёт в первый параметр процедуры оповещения. Если форму закрыли крестиком, результат будет Неопределено.

Сравнение способов блокировки

БлокироватьОкноВладельца

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

БлокироватьВесьИнтерфейс

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

Независимый режим без блокировки

Для справочных окон и параллельной работы. Не подходит, когда нужен результат до продолжения кода.

Устаревшие синхронные методы и режим модальности

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

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

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

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

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

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

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

Типичные ошибки
01
Код после ПоказатьВопрос() в той же процедуре — выполняется до ответа пользователя; переносите логику в обработчик оповещения
02
Отсутствие слова Экспорт у процедуры-обработчика — платформа не находит метод и выдаёт ошибку
03
Попытка открыть окно из серверной процедуры или фонового задания — интерфейс доступен только на клиенте
04
Использование ОткрытьФормуМодально() в управляемом приложении — метод запрещён без включения режима модальности
05
Отсутствие проверки результата на Неопределено — при отмене ввода код падает с ошибкой

Как проверить, что окно работает правильно

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

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

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

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

Реакция родительской формы при открытом окне
Норма

Клики по родительской форме игнорируются

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

Родительская форма доступна — режим блокировки не задан

Ответ пользователя
Норма

В обработчик приходит выбранный код возврата

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

Обработчик не вызывается — проверьте Экспорт и имя процедуры

Закрытие окна крестиком
Норма

В обработчик приходит Неопределено, код корректно завершается

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

Ошибка при обращении к результату

FAQ: частые вопросы о модальных окнах в 1С

Как открыть модальное окно в обычном приложении 1С 8.2/8.3?

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

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

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

Как передать данные из модальной формы обратно в вызывающую?

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

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

Нет. Интерфейсные вызовы доступны только на клиенте. Если решение о показе окна принимается на сервере, верните из серверной процедуры признак или данные на клиент и откройте окно уже в клиентском контексте.

Чем заменить Предупреждение() в управляемом приложении?

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

Работают ли модальные окна в веб-клиенте?

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

Итог

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

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