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

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

ОткрытьМодально в 1С: что это за метод и как правильно его заменить

Что такое ОткрытьМодально в 1С, почему метод устарел и запрещён, как заменить его на ОткрытьФорму с описанием оповещения. Примеры кода и типичные ошибки.

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

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

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

Как работает ОткрытьМодально и где он применялся

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

&НаКлиенте

Процедура ВыбратьКонтрагента(Команда)

ФормаВыбора = ПолучитьФорму("Справочник.Контрагенты.ФормаВыбора");

Результат = ФормаВыбора.ОткрытьМодально();

Если Результат <> Неопределено Тогда

Контрагент = Результат;

КонецЕсли;

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

Ключевая особенность видна в структуре кода: строка Результат = ФормаВыбора.ОткрытьМодально() ждёт закрытия окна, и следующая строка выполняется только после выбора пользователя. Это удобно для линейной логики, но именно такое ожидание блокирует клиентское приложение.

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

Почему метод запрещён в современных конфигурациях

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

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

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

Чем заменить ОткрытьМодально: ОткрытьФорму с оповещением

Штатная замена — метод ОткрытьФорму() с параметром «ОписаниеОповещения». Логика разбивается на две процедуры: первая открывает форму, вторая (обработчик оповещения) получает результат после её закрытия.

&НаКлиенте

Процедура ВыбратьКонтрагента(Команда)

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

ОткрытьФорму("Справочник.Контрагенты.ФормаВыбора", , ЭтотОбъект, , , , Оповещение);

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

&НаКлиенте

Процедура ПослеВыбораКонтрагента(Результат, ДопПараметры) Экспорт

Если Результат <> Неопределено Тогда

Контрагент = Результат;

КонецЕсли;

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

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

Порядок замены модального вызова
  1. 1
    Найдите вызов ОткрытьМодально и определите, что делают строки кода после него
  2. 2
    Создайте процедуру-обработчик с параметрами (Результат, ДополнительныеПараметры)
  3. 3
    Перенесите в обработчик весь код, зависящий от результата выбора
  4. 4
    Замените вызов на ОткрытьФорму с ОписаниемОповещения, указывающим на обработчик
  5. 5
    Проверьте работу в тонком клиенте и, если используется, в веб-клиенте

Замена модальных диалогов: вопросы, ввод значений, выбор файлов

Помимо ОткрытьМодально у форм, в старом коде встречаются блокирующие системные диалоги. У каждого есть асинхронная пара, работающая через то же описание оповещения.

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

Пример с вопросом перед удалением строки — типичный случай, где старый код «спотыкается» о запрет модальности:

&НаКлиенте

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

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

ПоказатьВопрос(Оповещение, "Удалить выбранную строку?", РежимДиалогаВопрос.ДаНет);

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

&НаКлиенте

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

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

// удаление строки

КонецЕсли;

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

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

Перед переходом на режим «Не использовать» нужно найти все проблемные места. Самый быстрый способ — глобальный поиск по конфигурации (пункт меню «Правка — Глобальный поиск» или Ctrl+Shift+F) по строкам: «ОткрытьМодально», «Вопрос(», «Предупреждение(», «ВвестиЗначение», «ВвестиСтроку», «ВвестиЧисло», «ВвестиДату», «.Выбрать()».

Дополнительно полезна проверка конфигурации: в меню «Конфигурация — Проверка конфигурации» установите флажок «Поиск некорректных ссылок» и проверки на устаревшие методы — конфигуратор укажет вызовы, несовместимые с текущим режимом модальности. Внешние инструменты статического анализа кода также умеют находить модальные вызовы как нарушение стандарта.

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

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

Режим модальности конфигурации
Норма

Установлено «Не использовать», код работает без ошибок

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

При вызове возникает исключение о запрете модальных окон

Поведение формы выбора
Норма

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

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

Результат всегда Неопределено — обработка осталась в исходной процедуре

Работа в веб-клиенте
Норма

Диалоги и формы открываются, результат обрабатывается

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

Функция молча не срабатывает или падает с ошибкой

Типичные ошибки при замене и ограничения подхода

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

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

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

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

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

Когда ОткрытьМодально ещё встречается и что с этим делать

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

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

Итог

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

ОткрытьМодально — устаревший блокирующий метод открытия форм. Современная замена — ОткрытьФорму с ОписаниемОповещения: результат обрабатывается в отдельной процедуре после закрытия формы. Не ослабляйте режим модальности конфигурации ради старого кода — переписывайте вызовы.

Частые вопросы

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

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

Чем ОткрытьМодально отличается от ОткрытьФорму?

ОткрытьМодально останавливает выполнение кода до закрытия формы и возвращает результат в точку вызова. ОткрытьФорму открывает окно и сразу продолжает выполнение; результат приходит позже в отдельную процедуру-обработчик оповещения.

Можно ли заставить ОткрытьМодально работать в режиме «Такси»?

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

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

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

Нужно ли переписывать старый код, если база работает и не жалуется?

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