Разработка и Конфигурация · 13 мин
Как сделать всплывающее окно в 1С
Как сделать всплывающее окно в 1С: ПоказатьПредупреждение, ПоказатьВопрос, ОповеститьПользователя и открытие формы. Примеры кода для управляемых форм.
Всплывающие окна в 1С — это способ сообщить пользователю о важном событии, задать ему вопрос с выбором ответа или вывести ненавязчивое уведомление в углу экрана. В управляемых формах (интерфейс «Такси») для этого используются методы глобального контекста: ПоказатьПредупреждение, ПоказатьВопрос, ПоказатьОповещениеПользователя и ОповеститьПользователя (сообщение, привязанное к полю формы). Также «всплывающим окном» часто называют открытие отдельной формы в модальном или блокирующем режиме.
Важное ограничение современной платформы: модальные вызовы старого стиля (Предупреждение(), Вопрос()) по умолчанию запрещены в конфигурациях со свойством «Режим использования модальности» = «Не использовать». Все примеры ниже написаны в асинхронном стиле с описаниями оповещений — именно так код будет работать и в тонком клиенте, и в веб-клиенте без изменения настроек.
Выбор конкретного метода зависит от задачи: блокировать ли работу пользователя до ответа, нужен ли результат выбора («Да/Нет», «ОК/Отмена»), требуется ли автоматическое закрытие окна через заданное время. Ниже разобраны все основные сценарии с готовым кодом.
Какие виды всплывающих окон есть в 1С
Платформа 1С:Предприятие предлагает четыре принципиально разных механизма, и их часто путают. Первый — диалог-предупреждение: окно с текстом и кнопкой «ОК», которое блокирует работу до нажатия. Второй — диалог-вопрос: окно с набором кнопок («Да», «Нет», «Отмена» и др.), результат нажатия возвращается в код через описание оповещения.
Третий механизм — оповещение пользователя: небольшое окно в правом нижнем углу экрана, которое не блокирует работу и может исчезнуть само. Четвёртый — открытие произвольной формы поверх текущей, когда нужен нестандартный диалог со своими полями и логикой.
Сравнение вариантов
Информационное окно с кнопкой ОК, блокирует работу. Подходит для ошибок и важных сообщений, результат не возвращается.
Диалог с кнопками Да/Нет/Отмена и другими. Результат приходит в процедуру-обработчик оповещения.
Окно в углу экрана, не блокирует работу, закрывается автоматически. Для фоновых уведомлений.
Своя форма с произвольными элементами. Максимальная гибкость, но требует создания формы в конфигураторе.
Как вывести простое предупреждение
Метод ПоказатьПредупреждение используется, когда нужно сообщить пользователю о проблеме или результате операции и дождаться подтверждения прочтения. Минимальный вызов выглядит так:
ПоказатьПредупреждение(, "Документ не проведён: не заполнен склад.");
Первый параметр — описание оповещения, которое будет вызвано после закрытия окна. Если после нажатия «ОК» ничего делать не нужно, передаётся Неопределено (или параметр опускается). Третий параметр — таймаут в секундах: если указать число, окно закроется само по истечении времени. Четвёртый — заголовок окна.
&НаКлиенте
Процедура ПередЗаписью(Отказ, ПараметрыЗаписи)
Если Не ЗначениеЗаполнено(Объект.Склад) Тогда
Отказ = Истина;
ПоказатьПредупреждение(, "Заполните склад перед записью.", , "Проверка данных");
КонецЕсли;
КонецПроцедуры
Если после закрытия предупреждения нужно продолжить логику — например, установить курсор на незаполненное поле — создаётся описание оповещения:
Оповещение = Новый ОписаниеОповещения("ПослеЗакрытияПредупреждения", ЭтотОбъект);
ПоказатьПредупреждение(Оповещение, "Заполните склад перед записью.");
&НаКлиенте
Процедура ПослеЗакрытияПредупреждения(ДополнительныеПараметры) Экспорт
ЭтотОбъект.ТекущийЭлемент = Элементы.Склад;
КонецПроцедуры
Обратите внимание: процедура-обработчик обязательно должна быть объявлена с ключевым словом Экспорт и находиться в клиентском контексте, иначе платформа не сможет её вызвать.
Как задать вопрос пользователю и получить ответ
Метод ПоказатьВопрос выводит окно с набором кнопок и возвращает код нажатой кнопки в обработчик оповещения. Типичный сценарий — подтверждение удаления или проведения документа:
&НаКлиенте
Процедура УдалитьСтроки(Команда)
Оповещение = Новый ОписаниеОповещения("УдалитьСтрокиЗавершение", ЭтотОбъект);
ПоказатьВопрос(Оповещение, "Удалить выбранные строки?", РежимДиалогаВопрос.ДаНет, 20, КодВозвратаДиалога.Нет);
КонецПроцедуры
&НаКлиенте
Процедура УдалитьСтрокиЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
// логика удаления
КонецЕсли;
КонецПроцедуры
Параметры вызова: описание оповещения, текст вопроса, режим диалога (набор кнопок), таймаут в секундах, кнопка по умолчанию. Если пользователь не ответит за время таймаута, в обработчик придёт значение КодВозвратаДиалога.Таймаут — этот случай стоит обрабатывать отдельно, иначе логика может сработать непредсказуемо.
Для нестандартного набора кнопок используется список значений вместо предопределённого режима: в него добавляются элементы с кодами возврата и произвольными подписями, например «Провести», «Записать без проведения», «Отмена».
Как показать ненавязчивое уведомление в углу экрана
Когда блокировать работу пользователя не нужно — например, фоновое задание завершилось или пришло сообщение из обмена — используется ПоказатьОповещениеПользователя. Окно появляется в углу, не перехватывает фокус и закрывается само:
ПоказатьОповещениеПользователя(
"Обмен завершён",
,
"Загружено документов: 15",
БиблиотекаКартинок.Информация,
СтатусОповещенияПользователя.Важное);
Второй параметр — навигационная ссылка: если её указать, текст становится гиперссылкой, по клику на которую открывается нужный объект (например, созданный документ). Это удобный способ дать пользователю быстрый переход к результату операции без модального окна.
Отдельно существует метод ОповеститьПользователя (сообщение пользователю), который выводит текст в панель сообщений и может привязываться к конкретному полю формы. Это не совсем «всплывающее окно», но именно его рекомендуется использовать для ошибок заполнения: сообщение появляется рядом с проблемным полем, и по клику курсор переходит к нему.
Как открыть свою форму как всплывающее окно
Если стандартных диалогов недостаточно — нужно запросить у пользователя несколько значений, показать список для выбора или вывести сложное сообщение — создаётся общая форма (или форма объекта) и открывается методом ОткрытьФорму в блокирующем режиме:
&НаКлиенте
Процедура ВыбратьПричину(Команда)
Оповещение = Новый ОписаниеОповещения("ВыбратьПричинуЗавершение", ЭтотОбъект);
ОткрытьФорму("ОбщаяФорма.ФормаВыбораПричины", , ЭтотОбъект, , , , Оповещение,
РежимОткрытияОкнаФормы.БлокироватьОкноВладельца);
КонецПроцедуры
&НаКлиенте
Процедура ВыбратьПричинуЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат <> Неопределено Тогда
Объект.ПричинаОтказа = Результат;
КонецЕсли;
КонецПроцедуры
Режим БлокироватьОкноВладельца делает форму «всплывающей»: пользователь не сможет вернуться к родительскому окну, пока не закроет диалог. Чтобы вернуть значение из такой формы, в её модуле при нажатии кнопки вызывается Закрыть(ВозвращаемоеЗначение) — это значение и придёт в обработчик оповещения.
Параметры в открываемую форму передаются вторым аргументом — структурой. В модуле формы они доступны через объект Параметры в обработчике ПриСозданииНаСервере, что позволяет настроить заголовок, список выбора и начальные значения под конкретный вызов.
- 1В конфигураторе создайте общую форму и разместите нужные поля и кнопки
- 2Для кнопки подтверждения напишите обработчик с вызовом Закрыть(Результат)
- 3В месте вызова создайте ОписаниеОповещения и процедуру-обработчик с Экспорт
- 4Вызовите ОткрытьФорму с режимом БлокироватьОкноВладельца
- 5Проверьте в обработчике, что Результат не равен Неопределено (окно могли закрыть крестиком)
Частые ошибки и ограничения
Самая распространённая ошибка — использование синхронных методов Предупреждение() и Вопрос() из старого API. В конфигурациях с запрещённой модальностью такой код выдаёт ошибку, а в веб-клиенте часто не работает вовсе. Проверить настройку можно в свойствах конфигурации: «Режим использования модальности». Рекомендуемое значение — «Не использовать», и весь код пишется асинхронно.
Вторая типичная проблема — обработчик оповещения без ключевого слова Экспорт или с неверным числом параметров. Платформа вызывает обработчик со строго определённой сигнатурой: для вопроса — (Результат, ДополнительныеПараметры), для предупреждения — (ДополнительныеПараметры). Несовпадение приводит к ошибке в момент закрытия окна, которую сложно заметить при разработке.
Третья ошибка — попытка показать окно из серверного кода или из обработчиков, где интерактивные вызовы запрещены (например, в некоторых событиях записи на сервере). Также не стоит показывать несколько окон подряд в цикле: асинхронная модель этого не позволяет корректно, и интерфейс «зависает» очередью диалогов. Если нужно задать несколько вопросов, их выстраивают в цепочку: обработчик первого вопроса вызывает второй.
Как проверить, что окно работает правильно
После внедрения кода проверьте поведение во всех клиентах, которые используются в организации: толстый, тонкий и веб-клиент могут отличаться в деталях отображения. Особое внимание уделите сценариям, где пользователь закрывает окно не кнопкой, а крестиком или по таймауту — обработчик должен корректно реагировать на все варианты.
Для вопросов с таймаутом проверьте, что по истечении времени выполняется безопасная ветка логики (обычно — отмена действия). Для собственных форм убедитесь, что повторное открытие работает корректно и в форму передаются актуальные параметры.
Как проверить результат
Выполняется обработчик оповещения, логика продолжается
Ошибка 'Процедура не обнаружена' — проверьте Экспорт и имя обработчика
Обработчик получает Неопределено или Таймаут, действие отменяется
Код трактует закрытие как согласие и выполняет операцию
Окно отображается и не блокирует браузер
Ошибка модальности — в коде остались синхронные вызовы
Часто задаваемые вопросы
Можно ли показать всплывающее окно из серверной процедуры?
Нет, методы ПоказатьПредупреждение, ПоказатьВопрос и ПоказатьОповещениеПользователя работают только на клиенте. Если проверка выполняется на сервере, верните из серверной функции признак или текст ошибки и покажите окно в клиентском коде после возврата.
Почему код с Вопрос() выдаёт ошибку «Использование модальных окон запрещено»?
В свойствах конфигурации установлен режим использования модальности «Не использовать» — это стандарт для современных конфигураций. Замените синхронный вызов Вопрос() на асинхронный ПоказатьВопрос с описанием оповещения, а Предупреждение() — на ПоказатьПредупреждение.
Как сделать, чтобы окно закрылось само через несколько секунд?
У ПоказатьПредупреждение и ПоказатьВопрос есть параметр «Таймаут» — количество секунд до автоматического закрытия. Учтите, что при срабатывании таймаута в обработчик вопроса приходит КодВозвратаДиалога.Таймаут, и этот случай нужно обработать отдельно от ответов пользователя.
Как передать в обработчик оповещения свои данные?
Третьим параметром конструктора Новый ОписаниеОповещения передаётся произвольное значение — обычно структура с нужными данными. В обработчике оно придёт как параметр ДополнительныеПараметры. Это позволяет не хранить промежуточные значения в реквизитах формы.
Чем отличается ПоказатьОповещениеПользователя от ОповеститьПользователя?
ПоказатьОповещениеПользователя выводит отдельное окошко в углу экрана, которое исчезает само, — это уведомление о событии. ОповеститьПользователя выводит сообщение в панель сообщений и может привязываться к полю формы — это инструмент для указания на ошибки заполнения.
Как сделать окно с нестандартными кнопками, например «Провести / Записать / Отмена»?
В ПоказатьВопрос вместо предопределённого РежимДиалогаВопрос передайте список значений: каждому элементу задайте значение (код возврата) и представление (текст кнопки). В обработчике сравнивайте результат с этими кодами. Для совсем сложных диалогов создайте собственную форму.
Что важно запомнить
В управляемых формах 1С используются асинхронные методы: ПоказатьПредупреждение для сообщений, ПоказатьВопрос с описанием оповещения для выбора, ПоказатьОповещениеПользователя для фоновых уведомлений и ОткрытьФорму в блокирующем режиме для сложных диалогов. Обработчики объявляются с Экспорт, вызовы делаются только на клиенте, а случаи таймаута и закрытия без ответа обрабатываются явно.