Как завершить работу программы 1С прямо из модального окна?

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

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

Почему не работает стандартное завершение?

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

Способ 1: Использование метода ПрекратитьРаботуСистемы()

Если нам необходимо закрыть программу «здесь и сейчас», невзирая на открытые окна и незавершенные процессы в интерфейсе, следует использовать метод ПрекратитьРаботуСистемы(). Рассмотрим его синтаксис подробнее.

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

Пример кода в модальной форме:


Процедура КнопкаВыходНажатие(Кнопка)
    // Параметр Ложь означает, что перезапуск системы не требуется
    ПрекратитьРаботуСистемы(Ложь);
КонецПроцедуры

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

Способ 2: Возврат значения в основную форму (мягкий способ)

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

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


Процедура КнопкаЗавершитьРаботуНажатие(Кнопка)
    // Закрываем модальную форму и возвращаем признак необходимости выхода
    ЭтаФорма.Закрыть("ЗавершитьРаботу");
КонецПроцедуры

Шаг 2. В основной форме, из которой вызывалось окно, анализируем результат вызова.


Процедура ОткрытьДополнительноеОкно()
    Результат = ФормаДоп.ОткрытьМодально();
    
    Если Результат = "ЗавершитьРаботу" Тогда
        // Теперь мы находимся в контексте основной формы, модальное окно закрыто
        // Можно безопасно вызывать штатное завершение
        ЗавершитьРаботуСистемы(Истина); // Параметр Истина запросит подтверждение, если нужно
    КонецЕсли;
КонецПроцедуры

Этот метод считается более профессиональным и «чистым», так как он не нарушает логику работы платформы и позволяет системе штатно завершить все фоновые процессы.

Способ 3: Использование обработчика ожидания

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

  1. Модальная форма возвращает результат в основную.
  2. Основная форма вместо прямой команды закрытия подключает процедуру, которая выполнится через долю секунды.
  3. Это позволяет полностью «развязать» стек вызовов модального окна и процедуру завершения работы.

Пример в основной форме:


Перем НужноЛиЗакрыть;

Процедура ВызовМодальногоОкна()
    Результат = Форма.ОткрытьМодально();
    Если Результат = "ЭкстренныйВыход" Тогда
        // Подключаем однократное выполнение процедуры завершения через 0.1 сек
        ПодключитьОбработчикОжидания("ИсполнитьЗавершениеСистемы", 0.1, Истина);
    КонецЕсли;
КонецПроцедуры

Процедура ИсполнитьЗавершениеСистемы() Экспорт
    ЗавершитьРаботуСистемы(Ложь);
КонецПроцедуры

Рекомендации для современной платформы (8.3)

Выясним причину, по которой в новых конфигурациях работа с модальными окнами вообще не рекомендуется. Начиная с версии платформы 8.3.3, 1С активно внедряет режим «Запрет использования модальных вызовов». Это связано с работой в веб-клиенте, где браузеры блокируют модальные окна.

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

Подведем итог: для быстрого и гарантированного результата в старом коде (обычные формы или совместимость) используйте ПрекратитьРаботуСистемы(). Для корректной и безопасной работы — используйте возврат значения из модальной формы в основную с последующим вызовом ЗавершитьРаботуСистемы().

← На главную