Как программно закрыть форму документа в 1С:Предприятие 8

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

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

Причина ошибки при использовании ПолучитьФорму

Разберем ситуацию, с которой столкнулся автор темы. Когда мы вызываем метод ПолучитьФорму, система пытается найти уже существующую форму с указанными параметрами или создать новую. Если форма уже открыта, повторный вызов метода Закрыть() сразу после ПолучитьФорму() может не сработать, так как метод возвращает ссылку на объект, но контекст выполнения может блокировать операцию, или система считает, что вы пытаетесь манипулировать новым экземпляром.

Основная ошибка заключается в том, что для управления формой нужно иметь прямую ссылку на тот экземпляр, который был открыт изначально. Если мы «теряем» эту ссылку, обращение к форме становится затруднительным. Проанализируем правильные подходы к решению этой проблемы.

Способ 1. Сохранение ссылки на форму в переменную

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

Рассмотрим пример кода:


&НаКлиенте
Перем ФормаПродаж; // Объявляем переменную на уровне модуля

&НаКлиенте
Процедура ОткрытьФормуРегистрации()
    // Получаем форму и сохраняем ссылку в нашу переменную
    ФормаПродаж = ПолучитьФорму("Документ.ЧекККМ.Форма.ФормаРегистрацииПродаж");
    ФормаПродаж.Открыть();
КонецПроцедуры

&НаКлиенте
Процедура ЗакрытьФормуРегистрации()
    // Проверяем, инициализирована ли переменная и открыта ли форма
    Если ФормаПродаж <> Неопределено И ФормаПродаж.Открыта() Тогда
        ФормаПродаж.Закрыть();
    КонецЕсли;
КонецПроцедуры

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

Способ 2. Использование механизма оповещений

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

Разберем по шагам, как это реализовать:

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

Пример кода внутри закрываемой формы:


&НаКлиенте
Процедура ОбработкаОповещения(ИмяСобытия, Параметр, Источник)
    Если ИмяСобытия = "ЗакрытьФормуРегистрацииЧекККМ" Тогда
        ЭтаФорма.Закрыть();
    КонецЕсли;
КонецПроцедуры

Теперь из любой другой точки программы мы можем «послать сигнал» этой форме:


&НаКлиенте
Процедура КомандаЗакрытия()
    Оповестить("ЗакрытьФормуРегистрацииЧекККМ");
КонецПроцедуры

Этот способ считается наиболее «чистым» в архитектуре 1С, так как он обеспечивает слабую связанность объектов (декаплинг).

Способ 3. Поиск формы среди открытых окон

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

Посмотрим на пример реализации:


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

Этот метод позволяет гарантированно найти форму, если она запущена в текущем сеансе пользователя.

Способ 4. Проблема модифицированности данных

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

Проанализируем пример кода для «тихого» закрытия:


&НаКлиенте
Процедура ПринудительноеЗакрытие()
    ЭтаФорма.Модифицированность = Ложь; // Снимаем признак изменений
    ЭтаФорма.Закрыть();
КонецПроцедуры

Внимание: используйте этот прием осторожно, так как все несохраненные данные пользователя будут потеряны без предупреждения.

Использование Ключа Уникальности

Если вы все же используете ПолучитьФорму, помните про параметр КлючУникальности. Если при открытии формы вы указали уникальный ключ, то для того чтобы получить ссылку именно на это окно (а не создать новое), в методе ПолучитьФорму нужно указать тот же самый ключ. Если ключ не совпадет, система создаст новый экземпляр формы в памяти, и вызов Закрыть() для нового экземпляра никак не повлияет на старый.

Подведем итог: наиболее надежным способом является сохранение ссылки в переменной или использование системы оповещений. Это гарантирует предсказуемое поведение интерфейса и отсутствие ошибок «Форма уже открыта».

← На главную