Как скрыть или заблокировать кнопку закрытия ('крестик') на форме документа в 1С:Предприятие 8.3?

Программист 1С v8.3 (Управляемые формы)
← На главную

Многие разработчики 1С сталкиваются с задачей управления поведением форм (для этого есть настройка видимости и доступности элементов формы), в частности, с необходимостью скрыть или полностью отключить кнопку закрытия (так называемый "крестик") на форме документа. Это может быть актуально для форм, предназначенных для ввода критически важных данных, для киосков или специализированных рабочих мест, где требуется строгий контроль над действиями пользователя. Рассмотрим, как мы можем решить эту задачу, используя стандартные средства платформы 1С:Предприятие 8.3.

Понимание проблемы

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

Решение 1: Использование свойства формы "ОтображатьКнопкуЗакрытия"

Мы можем попытаться управлять видимостью кнопки закрытия напрямую через свойство формы ОтображатьКнопкуЗакрытия. Это свойство, доступное как в конфигураторе, так и программно, предназначено для сокрытия кнопки закрытия и отключения стандартного действия по клавише Esc.

Установка свойства в конфигураторе

Перейдем в конфигуратор, откроем нужную форму документа. В окне "Свойства" формы найдем свойство ОтображатьКнопкуЗакрытия. Установим его значение в Ложь.

Аналогично, для более полного контроля над внешним видом окна, мы можем также рассмотреть свойство ОтображатьЗаголовок, установив его в Ложь, если нам нужно убрать и заголовок формы, что может создать более "безрамочный" вид или позволить запустить 1С на полный экран без заголовка окна.

Программная установка свойства

Мы также можем установить это свойство программно при открытии формы, используя программное изменение форм, например, в обработчике события ПриОткрытии:


&НаКлиенте
Процедура ПриОткрытии(Отказ)
    ЭтаФорма.ОтображатьКнопкуЗакрытия = Ложь;
КонецПроцедуры

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

Важный нюанс: режимы основного окна клиентского приложения

К сожалению, свойство ОтображатьКнопкуЗакрытия работает не во всех режимах клиентского приложения 1С. Оно оказывает прямое влияние на видимость кнопки закрытия и поведение клавиши Esc только в определенных режимах основного окна. К таким режимам относятся: РабочееМесто, ПолноэкранноеРабочееМесто или Киоск.

Если форма, с которой мы работаем, не является основным окном приложения или само приложение работает в режиме Обычный (который является режимом по умолчанию для большинства обычных форм документов), то установка свойства ОтображатьКнопкуЗакрытия = Ложь; не даст желаемого эффекта. Крестик закрытия останется видимым, и форма сможет быть закрыта пользователем. Этот факт объясняет, почему в диалоге на форуме первое предложение о программной установке этого свойства не помогло автору.

Мы можем установить режим основного окна через свойства конфигурации или программно. Например, мы можем попытаться установить для всего клиентского приложения режим "Рабочее место" или "Киоск". Это делается в конфигурации для всего клиентского приложения. Однако это глобальное изменение повлияет на все приложение, а не только на конкретную форму. Для большинства типовых задач по работе с отдельными формами документов это не является приемлемым решением.

Решение 2: Программная блокировка закрытия формы через событие "ПередЗакрытием"

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

Реализация обработчика события ПередЗакрытием

В обработчике события ПередЗакрытием формы, которое выполняется непосредственно перед попыткой закрытия формы, мы можем установить параметр Отказ в значение Истина. Это предотвратит закрытие формы, независимо от того, как пользователь пытается ее закрыть (через крестик, меню "Файл" -> "Закрыть", или нажатием клавиши Esc).


&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    // Устанавливаем Отказ = Истина, чтобы предотвратить закрытие формы.
    // Крестик остается видимым, но его нажатие не приведет к закрытию.
    Отказ = Истина; 
    // Опционально: здесь можно добавить логику,
    // например, проверку сохраненных данных или вывод сообщения пользователю.
КонецПроцедуры

Если нам нужно, чтобы закрытие формы зависело от какого-либо условия, например, от значения определенного реквизита формы, мы можем реализовать это следующим образом:


&НаКлиенте
// Создадим реквизит формы с типом Булево, например, "НельзяЗакрыватьФорму"
// По умолчанию можно установить Истина, если форма должна быть постоянно открытой
// или Ложь, если закрытие должно быть разрешено изначально.

Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Отказ = НельзяЗакрыватьФорму; 
    // Если НельзяЗакрыватьФорму = Истина, форма не закроется.
    // Если НельзяЗакрыватьФорму = Ложь, форма закроется.
КонецПроцедуры

Таким образом, мы получаем полный программный контроль над моментом закрытия формы. Мы можем динамически менять значение реквизита НельзяЗакрыватьФорму в зависимости от состояния данных или действий пользователя.

Обеспечение альтернативного способа закрытия

Критически важно помнить: если мы блокируем стандартный способ закрытия формы, мы обязательно должны предоставить пользователю альтернативный контролируемый способ выйти из формы. Обычно это реализуется в виде отдельной кнопки на форме, например, "Закрыть", "Сохранить и закрыть" или "Отмена".

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


&НаКлиенте
// Допустим, у нас есть реквизит формы "РазрешитьЗакрытиеФормы" с типом Булево.
// Изначально он может быть Ложь, чтобы блокировать закрытие.

Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Если Не РазрешитьЗакрытиеФормы Тогда
        Отказ = Истина; // Отменяем закрытие, если флаг не установлен
    КонецЕсли;
КонецПроцедуры

Процедура КомандаЗакрытьНажать(Команда)
    // Здесь мы выполняем всю необходимую логику:
    // 1. Проверяем корректность данных.
    // 2. Сохраняем или проводим документ.
    // 3. Выполняем другие действия, связанные с завершением работы с формой.

    // ... Ваша логика сохранения и обработки ...

    // После успешного выполнения всех действий:
    РазрешитьЗакрытиеФормы = Истина; // Устанавливаем флаг, разрешающий закрытие
    ЭтаФорма.Закрыть(); // Программно закрываем форму
КонецПроцедуры

Этот подход гарантирует, что форма закроется только тогда, когда это предусмотрено нашей логикой, и все необходимые действия будут выполнены.

Условное закрытие и запрос подтверждения пользователя

Мы также можем использовать событие ПередЗакрытием для того, чтобы запросить подтверждение у пользователя, особенно если на форме есть несохраненные изменения. Это предотвращает случайную потерю данных.


&НаКлиенте
Процедура ПередЗакрытием(Отказ, ЗавершениеРаботы, ТекстПредупреждения, СтандартнаяОбработка)
    Если ЕстьНесохраненныеДанныеНаФорме() Тогда // Здесь должна быть Ваша функция проверки наличия изменений
        Ответ = ПоказатьВопрос(ВопросДиалога.ДаНет, 
                              "На форме есть несохраненные данные. Закрыть без сохранения?", 
                              Таймаут = 0, 
                              КодВозвратаДиалога.Нет);
        Если Ответ = КодВозвратаДиалога.Нет Тогда
            Отказ = Истина; // Отменяем закрытие, если пользователь выбрал "Нет"
        Иначе
            Отказ = Ложь; // Разрешаем закрытие, если пользователь выбрал "Да"
        КонецЕсли;
    КонецЕсли;
КонецПроцедуры

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

Особенности закрытия клиентского приложения

Важно учитывать, что механизм обработки события ПередЗакрытием имеет свои особенности, когда происходит закрытие всего клиентского приложения, а не только одной формы. В этом сценарии существуют определенные ограничения: запрещено открывать любые новые формы и диалоги, а также выполнять любые серверные вызовы. Если в такой ситуации мы установим Отказ = Истина;, это может привести к отображению системного предупреждения или текста, который мы зададим разработчиком в параметре ТекстПредупреждения, но не к полному предотвращению закрытия всего приложения. Платформа 1С все равно попытается завершить работу, выдавая предупреждение, так как полное блокирование закрытия приложения может нарушить стабильность системы.

Альтернативные подходы и контекст использования

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

  1. Управление видимостью элементов формы: Для элементов, которые находятся непосредственно внутри формы (например, кнопок или полей ввода), мы можем использовать свойства Пользовательская видимость, Просмотр, Редактирование и Видимость. Эти свойства доступны как в конфигураторе, так и программно. Однако, это относится только к элементам, которые мы сами разместили на форме, и не применимо к системной кнопке закрытия окна (крестику), которая является частью рамки окна операционной системы.
  2. Особенности веб-клиента: При работе в веб-клиенте браузеры могут вводить дополнительные ограничения на возможности программного кода 1С, особенно в части закрытия окон без интерактивного взаимодействия с пользователем. Это обусловлено политиками безопасности браузеров, которые стремятся предотвратить нежелательное закрытие вкладок или окон без явного действия пользователя.
  3. Исторический контекст: В более ранних версиях 1С (например, 7.7), где не было концепции управляемых форм, вопросы блокировки закрытия формы также были актуальны. Они часто решались через управление записью данных и предотвращение потери информации при попытке закрытия окна формы, что демонстрирует давнюю потребность в таком контроле.

Вывод

Мы видим, что для большинства форм документов в 1С:Предприятии 8.3, которые не являются основным окном приложения, наиболее надежным и рекомендуемым способом "убрать" или "отключить" функциональность крестика закрытия является программная блокировка через обработчик события ПередЗакрытием с установкой параметра Отказ = Истина;. При этом обязательно следует предусмотреть альтернативный, контролируемый способ выхода из формы для пользователя.

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

Выбор конкретного подхода зависит от контекста использования формы, требуемого уровня контроля и общего дизайна пользовательского интерфейса приложения.

← На главную