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

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

Как закрыть форму в 1С: способы для пользователя и программиста

Как закрыть форму в 1С: метод Закрыть(), комбинации клавиш, закрытие из кода тонкого и управляемого приложения, обработка модифицированности и типичные ошибки.

Форма в 1С закрывается либо действием пользователя — кнопкой крестика, клавишей Esc или командой интерфейса, либо программно методом Закрыть() из встроенного языка. Какой способ выбрать, зависит от контекста: обычное приложение или управляемые формы, нужно ли сохранять изменённые данные перед закрытием и откуда вызывается команда. Ошибки чаще всего связаны с тем, что разработчик пытается закрыть форму на сервере или не обрабатывает модифицированность.

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

Как пользователю закрыть форму без программирования

В обычной работе форма закрывается стандартными средствами интерфейса. Нажатие на крестик в заголовке окна или вкладки, клавиша Esc, сочетание Ctrl+F4 — все эти действия приводят к одному результату: платформа инициирует закрытие формы. Если данные на форме не менялись, она закроется мгновенно.

Если в документе или элементе справочника что-то редактировали, платформа покажет вопрос «Данные были изменены. Сохранить изменения?». Это встроенное поведение, отключать его в типовой работе не нужно — оно защищает от потери введённой информации. Ответ «Да» записывает объект и закрывает форму, «Нет» закрывает без записи, «Отмена» возвращает к редактированию.

В тонком клиенте и веб-клиенте управляемые формы открываются в закладках основного окна. Закрыть активную закладку можно крестиком на самой закладке или через контекстное меню «Закрыть». Команда «Закрыть все» в меню закладок закрывает все открытые формы — удобно в конце рабочего дня, но сначала убедитесь, что нигде не остались несохранённые документы.

Программное закрытие формы методом Закрыть()

Для закрытия формы из кода используется метод Закрыть(). В модуле самой формы вызов выглядит так:

&НаКлиенте

Процедура КомандаГотово(Команда)

ЭтаФорма.Закрыть();

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

Метод принимает необязательный параметр — значение, которое вернётся как результат закрытия. Это важно для форм, открытых через ОткрытьФормуМодально() или с ожиданием результата: вызывающий код получит переданное значение после закрытия. Например, Закрыть(ВыбранноеЗначение) вернёт выбор пользователя в форму-родителя.

Ключевое ограничение: Закрыть() работает только в клиентском контексте. Вызов метода в серверной процедуре (&НаСервере) приведёт к ошибке, потому что сервер не управляет окнами на компьютере пользователя. Если логика требует серверных проверок перед закрытием, выполните их на сервере, верните результат в клиентскую процедуру и уже там вызывайте Закрыть().

bsl
&НаКлиенте
Процедура ЗаписатьИЗакрыть(Команда)
	Если ПроверитьДанныеНаСервере() Тогда
		ЭтаФорма.Закрыть();
	Иначе
		ПоказатьПредупреждение(, "Проверьте заполнение полей");
	КонецЕсли;
КонецПроцедуры

Как закрыть форму из другой формы или из общего модуля

Частая задача — закрыть форму не из неё самой, а извне: например, после записи документа закрыть открытую форму списка, чтобы она обновилась. Для этого нужна ссылка на объект формы. Получить её можно несколькими путями: сохранить результат ОткрытьФорму() в переменную, найти форму через ПолучитьФорму() или передать ссылку на форму при открытии.

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

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

Обработка закрытия: ПередЗакрытием и ПриЗакрытии

Платформа предоставляет два события, связанных с закрытием формы. ПередЗакрытием вызывается до закрытия и позволяет его отменить: установка параметра Отказ = Истина оставит форму открытой. Именно здесь типовые конфигурации задают вопрос о сохранении изменений, если установлен признак Модифицированность.

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

Типичный шаблон защиты от потери данных выглядит так:

&НаКлиенте

Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)

Если Модифицированность Тогда

Отказ = Истина;

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

ПоказатьВопрос(ОписаниеОповещения, "Сохранить изменения?", РежимДиалогаВопрос.ДаНетОтмена);

КонецЕсли;

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

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

Порядок действий при добавлении кнопки закрытия
  1. 1
    Откройте модуль формы и добавьте клиентскую процедуру команды
  2. 2
    Внутри процедуры вызовите ЭтаФорма.Закрыть() с нужным возвращаемым значением или без него
  3. 3
    Перетащите команду на форму в конфигураторе или создайте кнопку программно
  4. 4
    Проверьте, что обработчик ПередЗакрытием не блокирует закрытие при несохранённых данных
  5. 5
    Протестируйте сценарии: закрытие без изменений, с изменениями и ответом «Отмена»

Закрытие модальных и блокирующих форм

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

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

Если форма открыта с параметром РежимОткрытияОкна = БлокироватьВесьИнтерфейс, пользователь не сможет переключиться на другие окна, пока форма не закрыта. Убедитесь, что у такой формы всегда есть доступный способ закрытия — видимая кнопка или работающий Esc, иначе пользователь окажется заблокирован и сможет выйти только через принудительное завершение сеанса.

Типичные ошибки и как их избежать

Самая распространённая ошибка — вызов Закрыть() на сервере. Компилятор модуля формы такой код пропустит, а ошибка проявится только в момент выполнения. Правило простое: все команды интерфейса, включая закрытие, выполняются в процедурах с директивой &НаКлиенте.

Вторая частая проблема — повторный вопрос о сохранении. Разработчик в обработчике вопроса записывает объект, но забывает, что запись может снова установить модифицированность (например, из-за пересчёта в ПослеЗаписи). Решение — перед повторным вызовом Закрыть() явно сбросить флаг: Модифицированность = Ложь, если данные действительно сохранены.

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

Типичные ошибки
01
Вызов Закрыть() в серверной процедуре — ошибка выполнения, так как сервер не управляет окнами
02
Игнорирование возвращаемого значения Неопределено при закрытии формы крестиком — обращение к полям результата вызывает ошибку
03
Отсутствие обработки Модифицированности — пользователь теряет введённые данные без предупреждения
04
Закрытие формы через ПолучитьФорму() — создаётся новый экземпляр формы только для закрытия
05
Длительные операции в ПриЗакрытии — визуальное зависание при закрытии окна

Как проверить, что закрытие работает правильно

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

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

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

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

Закрытие без изменений
Норма

Форма закрывается сразу, без диалогов

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

Появляется вопрос о сохранении — значит, модифицированность устанавливается лишний раз

Закрытие с изменениями
Норма

Вопрос о сохранении, все три ответа работают корректно

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

Форма закрывается молча, данные теряются

Программное закрытие
Норма

Закрыть() вызывается только в клиентских процедурах

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

Ошибка выполнения при вызове из серверного кода

Возвращаемое значение
Норма

Вызывающий код обрабатывает Неопределено

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

Ошибка при закрытии формы крестиком

Итог

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

Пользователь закрывает форму клавишей Esc, крестиком или Ctrl+F4; программно — методом Закрыть() только на клиенте. Вопрос о сохранении обрабатывается в ПередЗакрытием через асинхронный диалог, а финальные действия — в ПриЗакрытии. Всегда проверяйте возвращаемое значение на Неопределено и не пытайтесь обойти защитные обработчики закрытия.

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

Как закрыть форму без сохранения изменений программно?

Сначала сбросьте признак изменений: Модифицированность = Ложь, затем вызовите ЭтаФорма.Закрыть(). Без сброса флага сработает обработчик ПередЗакрытием и покажет вопрос о сохранении. Используйте этот приём только там, где потеря введённых данных — осознанное решение пользователя.

Почему Закрыть() выдаёт ошибку «Метод не обнаружен»?

Чаще всего метод вызван в серверной процедуре или у объекта, который не является формой. Проверьте директиву компиляции процедуры — должна быть &НаКлиенте — и тип переменной, у которой вызывается метод. У формы-объекта на сервере метода Закрыть() нет.

Как запретить закрытие формы пользователем?

В обработчике ПередЗакрытием установите Отказ = Истина при нужном условии. Полностью убрать крестик окна нельзя, но можно перехватывать его нажатие этим событием. Учтите: при завершении работы программы параметр ЗавершениеРаботы равен Истина, и блокировать закрытие в этом случае нельзя — платформа всё равно завершит сеанс.

Чем отличается Закрыть() от УстановитьВидимость(Ложь)?

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

Как закрыть все открытые формы разом?

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

Работает ли Esc для закрытия в управляемых формах?

Да, клавиша Esc по умолчанию инициирует закрытие формы, если у кнопки закрытия или формы не переопределено сочетание клавиш. Если Esc не срабатывает, проверьте, не назначено ли это сочетание другой команде формы, и не блокирует ли закрытие обработчик ПередЗакрытием.