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