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