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