Почему управляемая форма 1С открывается и сразу закрывается без выполнения процедуры ПередЗакрытием

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

При разработке конфигураций и расширений на платформе 1С:Предприятие 8.3 разработчики могут столкнуться с нестандартным поведением управляемых форм: форма визуально «моргает» на экране и моментально закрывается. При этом точка останова в обработчике ПередЗакрытием не срабатывает, однако процедура ПриЗакрытии успешно выполняется. В этой статье мы подробно проанализируем причины этого явления и разберем способы его устранения.

Анализ жизненного цикла формы и причин пропуска события ПередЗакрытием

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

  1. ПриСозданииНаСервере — серверная инициализация объекта и реквизитов формы.
  2. ПередОткрытием — клиентская проверка условий перед отображением окна.
  3. ПриОткрытии — событие, вызываемое в момент успешного визуального отображения формы.
  4. ПередЗакрытием — интерактивный обработчик, позволяющий отменить закрытие через параметр Отказ.
  5. ПриЗакрытии — завершающее событие деструктора формы, срабатывающее всегда при уничтожении объекта.

Если на этапе ПриСозданииНаСервере или ПередОткрытием происходит системный сбой, устанавливается параметр Отказ = Истина или возникает ошибка в графическом менеджере окон, форма считает свой запуск незавершенным. В таком случае платформа пропускает этапы ПриОткрытием и ПередЗакрытием, но принудительно вызывает ПриЗакрытии для корректной очистки ресурсов памяти.

Причина 1: Конфликт режимов блокировки интерфейса (Стек блокирующих окон)

Рассмотрим частый сценарий из практики. В коде выполняется открытие формы в режиме блокировки всего интерфейса:


Процедура ПереместитьТекущийЭтап(СтруктураОснования) Экспорт
    ПараметрыФормы = Новый Структура("СтруктураОснования", СтруктураОснования);
    Рез = ОткрытьФорму("ОбщаяФорма.ПеремещениеЭтапа", ПараметрыФормы, , , , , , РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс);
КонецПроцедуры

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

Решение: Изменение режима открытия окна и указание владельца

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

Рассмотрим исправленный пример кода:


Процедура ПереместитьТекущийЭтап(СтруктураОснования) Экспорт
    ПараметрыФормы = Новый Структура("СтруктураОснования", СтруктураОснования);
    
    // Передаем ЭтаФорма в качестве владельца и блокируем только окно-владелец
    ОткрытьФорму(
        "ОбщаяФорма.ПеремещениеЭтапа", 
        ПараметрыФормы, 
        ЭтаФорма, 
        , 
        , 
        , 
        , 
        РежимОткрытияОкнаФормы.БлокироватьОкноВладельца
    );
КонецПроцедуры

Причина 2: Ограничения прав доступа (RLS) и ошибки инициализации

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

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


&НаСервере
Процедура ПриСозданииНаСервере(Отказ, СтандартнаяОбработка)
    Попытка
        // Чтение данных и инициализация реквизитов формы
        ЗаполнитьДанныеФормы();
    Исключение
        // Логируем ошибку или информируем пользователя
        ВызватьИсключение "Недостаточно прав для открытия формы или произошла ошибка инициализации: " + ОписаниеОшибки();
        Отказ = Истина;
    КонецПопытки;
КонецПроцедуры

Рекомендации по корректному открытию форм

  1. Избегайте избыточной блокировки интерфейса: Используйте РежимОткрытияОкнаФормы.БлокироватьВесьИнтерфейс только в крайних случаях, когда действительно требуется полностью приостановить работу пользователя во всех окнах системы.
  2. Всегда указывайте владельца формы: При открытии модальных или блокирующих окон передавайте аргумент Владелец (обычно ЭтаФорма), чтобы платформа могла построить четкую иерархию окон.
  3. Проверяйте права до вызова формы: Перед вызовом функции ОткрытьФорму выполняйте проверку прав доступа с помощью функции ПравоДоступа(), чтобы не производить лишние попытки открытия недоступных форм.
← На главную