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