Как заменить модальные окна и функции Вопрос/Предупреждение в 1С:Предприятие 8.3?

Программист 1С v8.3 (Обычные формы) IT и автоматизация бизнеса
← На главную

При работе в конфигурациях 1С на базе платформы 8.3 (например, ЗКГУ, ЗУП, ERP, БП) разработчики часто сталкиваются с ситуацией, когда привычные синхронные функции Вопрос(), Предупреждение() и метод ОткрытьФормуМодально() перестают работать. Платформа выдает ошибку о запрете использования модальных окон. В этой статье мы подробно разберем, почему возникла эта проблема, как корректно переписать код для организации диалога с пользователем и какие инструменты платформы помогают автоматизировать этот процесс.

Почему 1С отказывается от модальных окон?

Рассмотрим первопричины отключения модальности. Переход платформы «1С:Предприятие» на работу в веб-клиентах и мобильных приложениях потребовал изменения архитектуры работы с интерфейсом:

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

Многие разработчики пытаются решить проблему простым включением свойства конфигурации МодальныйРежим = Истина. Однако это временное решение, которое ломает совместимость с веб-клиентом и стандартами разработки БСП. Разберем правильные способы организации немодального диалога.

Способ 1. Использование методов ПоказатьВопрос() и ОписаниеОповещения

Проанализируем классический подход, применяемый начиная с платформы 8.3.3. Вместо синхронной функции Вопрос() используется немодальный метод ПоказатьВопрос(), которому передается объект ОписаниеОповещения.

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

Рассмотрим пример реализации выборки номенклатуры или подтверждения действия:


&НаКлиенте
Процедура ВыполнитьУдалениеЗаписи(Команда)
    
    // Формируем описание оповещения, указывая имя процедуры-обработчика и текущий контекст (ЭтотОбъект)
    ПараметрыОповещения = Новый Структура("ИдентификаторСтроки", Элементы.Таблица.ТекущаяСтрока);
    Оповещение = Новый ОписаниеОповещения("ВыполнитьУдалениеЗаписиЗавершение", ЭтотОбъект, ПараметрыОповещения);
    
    // Вызываем немодальный диалог
    ПоказатьВопрос(Оповещение, "Вы действительно хотите удалить выбранную запись?", РежимДиалогаВопрос.ДаНет);
    
    // ВНИМАНИЕ: Код, написанный здесь, выполнится СРАЗУ, не дожидаясь ответа пользователя!

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

&НаКлиенте
Процедура ВыполнитьУдалениеЗаписиЗавершение(РезультатДиалога, ДополнительныеПараметры) Экспорт
    
    // Процедура вызывается платформой после нажатия кнопки в окне вопроса
    Если РезультатДиалога = КодВозвратаДиалога.Да Тогда
        
        // Получаем переданные доп. параметры
        ИдСтроки = ДополнительныеПараметры.ИдентификаторСтроки;
        УдалитьСтрокуНаСервере(ИдСтроки);
        
    КонецЕсли;

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

Разберем ключевые требования к процедуре-обработчику оповещения:

  1. Процедура обязательно должна иметь директиву &НаКлиенте и ключевое слово Экспорт.
  2. Процедура должна принимать минимум два обязательных параметра: первый содержит результат ответа пользователя (например, КодВозвратаДиалога.Да), второй — структуру с дополнительными параметрами ДополнительныеПараметры.

Способ 2. Автоматический рефакторинг в Конфигураторе

Для ускорения перевода старого кода с модальных вызовов на немодальные в Конфигураторе 1С предусмотрен встроенный механизм рефакторинга. Выясним, как им пользоваться по шагам:

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

Способ 3. Асинхронные функции и оператор Ждать (Платформа 8.3.18 и выше)

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

Посмотрим, как выглядит линейный код с применением этой технологии:


&НаКлиенте
Асинх Процедура УдалитьЗаписьКлиент(Команда)
    
    // Оператор Ждать приостанавливает выполнение процедуры до ответа пользователя,
    // но при этом не блокирует интерфейс и браузер
    Ответ = Ждать ВопросАсинх("Удалить выбранную строку?", РежимДиалогаВопрос.ДаНет);
    
    Если Ответ = КодВозвратаДиалога.Да Тогда
        // Код продолжит выполняться последовательно в этой же процедуре
        УдалитьЗаписьНаСервере();
        ПоказатьОповещениеПользователя("Успешно", , "Запись удалена");
    КонецЕсли;

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

Использование конструкции Асинх / Ждать сохраняет привычный линейный стиль написания кода, исключая необходимость плодить множественные процедуры-завершения.

Работа с немодальными окнами в Обычном приложении

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

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

  1. В меню Конфигуратора выберите пункт Конфигурация -> Проверка конфигурации.
  2. Установите флажки Поиск использования модальных окон и Поиск использования синхронных вызовов.
  3. Запустите проверку. Платформа сформирует список всех мест, требующих переработки.

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

← На главную