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