Так как мы рассматриваем ситуацию записи объекта и закрытия его формы, то после обработки на клиенте события После записи на клиенте же вызывается событие Перед закрытием.
Основное назначение этого события – проанализировать, можно закрывать форму или нельзя. И если нельзя, то отказаться от ее закрытия. Описание процедуры обработчика этого события выглядит следующим образом (листинг 3.33).
Листинг 3.33. Объявление обработчика события «Перед закрытием»
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Установка параметра Отказ в значение Истина позволяет отказаться от закрытия формы. А запрет стандартной обработки (СтандартнаяОбработка = Ложь) позволяет отказаться от стандартных действий, которые опять-таки определяются типом основного реквизита формы.
Например, в случае с формой справочника стандартные действия платформы будут заключаться в следующем. Если форма модифицирована и окно формы закрывается клавишей Esc или нажатием кнопки закрытия окна, то платформа сообщит о том, что данные формы модифицированы, и предложит либо записать их, либо закрыть без сохранения изменений, либо отказаться от закрытия формы.
Если в этой ситуации отказаться от стандартной обработки, то форма будет закрыта без вопросов в любом случае, независимо от того, модифицированы в ней данные или нет.
С помощью параметра ЗавершениеРаботы разработчик может определить, закрывается форма «сама по себе» или форма закрывается в процессе завершения работы приложения. Данный параметр устанавливается в значение Истина в том случае, если пользователь пытается закрыть основное окно приложения. При закрытии отдельной формы данный параметр будет установлен в значение Ложь.
При закрытии всего приложения и при отказе от закрытия конкретной формы с помощью параметра ТекстПредупреждения разработчик может установить текстовое сообщение, которое будет показано пользователю, с возможностью отказаться от закрытия или подтвердить его (в веб-клиенте все сообщения будут объединены в один диалог).
Если параметр ТекстПредупреждения не установлен, то в качестве текста предупреждения в диалоге будет показана строка «Работа в данном окне не завершена».
Нужно помнить, что при обработке завершения работы приложения в обработчиках событий ПередЗавершениемРаботыСистемы, ПриЗавершенииРаботыСистемы, а также в обработчиках событий формы, находящейся в режиме закрытия (ПередЗакрытием, ПриЗакрытии), запрещено открывать окна и выполнять любые серверные вызовы. Поэтому рекомендуется заранее сохранить в данных формы ту информацию, которая может потребоваться, чтобы определить, можно закрыть форму при завершении работы приложения или нет.
Как уже говорилось, при закрытии форм прикладных объектов (по отдельности или в случае закрытия основного окна приложения), если данные были изменены, платформа предупредит об этом и не даст закрыть окно без подтверждения пользователя. Это поведение не требует вмешательства разработчика, в случае если стандартная обработка события ПередЗакрытием не отменена.
В противном случае, или если форма произвольная (т. е. прикладной объект не является основным реквизитом формы), или это, например, форма обработки, разработчик должен самостоятельно реализовать принятый в платформе единый подход к закрытию форм и основного окна приложения.
В обработчике события ПередЗакрытием по значению параметра ЗавершениеРаботы разработчик должен определить, закрывается ли форма в процессе завершения работы приложения. Если да, то разработчик, проанализировав данные формы, принимает решение, нужно ли выдать пользователю какое-либо сообщение, требующее реакции пользователя: завершить работу или все-таки продолжить работу, т. к. в форме есть существенная информация.
Если параметр ЗавершениеРаботы имеет значение Ложь, то это означает, что закрывается отдельная форма. В этом случае логика работы выглядит следующим образом:
Поясним вышесказанное на примере.
Примечание
Пример можно посмотреть в демонстрационной базе «Открытие форм», форма обработки ЗакрытиеФормы.
В форме обработки ЗакрытиеФормы содержится булевый реквизит ПредупреждениеОЗакрытии, который отображается в форме в виде флажка. Для упрощения примера вместо «настоящего» анализа данных формы мы будем использовать состояние этого флажка в качестве признака того, надо ли показывать пользователю предупреждение с вопросом о возможности закрытия формы или закрывать ее сразу, без вопросов.
Рассмотрим обработчик события формы ПередЗакрытием (листинг 3.34).
Листинг 3.34. Обработчик события «Перед закрытием»
&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
Если НЕ ПредупреждениеОЗакрытии Тогда
Возврат;
КонецЕсли;
Если НЕ ЗавершениеРаботы Тогда
Если ОтветПередЗакрытием <> Истина Тогда
Отказ = Истина;
ОповещениеОЗакрытии = Новый ОписаниеОповещения("ПередЗакрытиемЗавершение", ЭтотОбъект);
ПоказатьВопрос(ОповещениеОЗакрытии, "Вы хотите закрыть форму?", РежимДиалогаВопрос.ДаНет);
КонецЕсли;
Иначе
Отказ = Истина;
ТекстПредупреждения = "При закрытии формы все данные будут утеряны. Продолжить?";
КонецЕсли;
КонецПроцедуры
Прежде всего, если флажок ПредупреждениеОЗакрытии не установлен, то ничего не происходит и форма закрывается без вопросов.
В противном случае, если параметр ЗавершениеРаботы имеет значение Истина, то форма закрывается в процессе завершения работы приложения.
В этом случае параметр Отказ мы устанавливаем в значение Истина и задаем в параметре ТекстПредупреждения сообщение, которое будет показано пользователю перед закрытием формы обработки.
Если параметр ЗавершениеРаботы имеет значение Ложь, значит, форма обработки закрывается, как обычно, кнопкой Закрыть.
В этом случае мы проверяем значение клиентской переменной модуля формы ОтветПередЗакрытием. Если это значение истинно, значит, ответ пользователя на вопрос о возможности закрытия формы уже был получен, и форма действительно закрывается. Если значение переменной ОтветПередЗакрытием не определено, значит, вопрос перед закрытием формы пользователю еще не задавался.
В этом случае параметр Отказ мы устанавливаем в значение Истина и создаем описание оповещения, определяющее процедуру, которая будет выполнена, после того как пользователь ответит на вопрос. Вопрос о возможности закрытия формы задаем пользователю с помощью немодального метода ПоказатьВопрос() и передаем туда первым параметром описание оповещения.
Процедура обработки оповещения ПередЗакрытиемЗавершение() выглядит следующим образом (листинг 3.35).
Листинг 3.35. Процедура «ПередЗакрытиемЗавершение»
&НаКлиенте
Процедура ПередЗакрытиемЗавершение(Результат, ДополнительныеПараметры) Экспорт
Если Результат = КодВозвратаДиалога.Да Тогда
ОтветПередЗакрытием = Истина;
Закрыть();
Иначе
ОтветПередЗакрытием = Неопределено;
КонецЕсли;
КонецПроцедуры
В процедуре обработки оповещения, в случае если пользователь согласился с закрытием формы, переменная ОтветПередЗакрытием устанавливается в значение Истина, и форма закрывается еще раз методом Закрыть(). Если нет, то форма остается открытой и переменная ОтветПередЗакрытием устанавливается в значение Неопределено.
Таким образом, мы задаем пользователю вопрос о возможности закрытия формы в обработчике события ПередЗакрытием. Обработчик вызывается дважды. Первый раз – когда закрытие формы (отдельно или при завершении работы приложения) инициируется пользователем, а второй – из встроенного языка после подтверждения пользователя. Но вопрос задается пользователю только в первый раз, если переменная ОтветПередЗакрытием не определена.
Остается только объявить эту клиентскую переменную в модуле формы (листинг 3.36).
Листинг 3.36. Объявление клиентской переменной «ОтветПередЗакрытием»
&НаКлиенте
Перем ОтветПередЗакрытием;
В результате в режиме 1С:Предприятие при закрытии формы обработки кнопкой Закрыть и при установленном флажке Предупреждение о закрытии пользователю будет показан следующий диалог, в котором он может подтвердить закрытие формы или отказаться от него (рис. 3.36).

Рис. 3.36. Вопрос пользователю перед закрытием формы обработки
А при закрытии формы обработки в процессе завершения работы приложения пользователю будет показан следующий диалог (рис. 3.37).

Рис. 3.37. Вопрос пользователю перед закрытием формы обработки