В процессе работы с 1С:ERP 2.4 часто возникает необходимость дисциплинировать пользователей, например, напоминать бухгалтеру или кассиру о необходимости закрытия кассовой смены перед выходом из программы. Поскольку конфигурация находится на поддержке, использование расширений является единственно правильным способом внесения подобных изменений без снятия базы с поддержки. В этой статье мы разберем по шагам, как реализовать проверку при закрытии системы, учитывая специфику современных версий платформы 1С.
Для решения задачи нам необходимо перехватить глобальное событие завершения работы системы. В современных версиях платформы (начиная с 8.3.15) разработчикам предоставлена возможность расширять Модуль управляемого приложения. Это позволяет внедрить свой код в процедуру ПередЗавершениемРаботыСистемы.
Рассмотрим алгоритм создания такого расширения:
&Перед.Проанализируем пример кода, который позволит прервать завершение работы, если пользователь не подтвердил свои действия:
&Перед("ПередЗавершениемРаботыСистемы")
Процедура Расш1_ПередЗавершениемРаботыСистемы(Отказ)
// Проверяем, относится ли текущий пользователь к тем, кому нужно выводить сообщение
Если НужноВыводитьНапоминание() Тогда
// Важно: в современном интерфейсе нельзя использовать модальные окна
// Платформа требует асинхронного подхода
Если Не ПроверитьСтатусКассовойСмены() Тогда
// Если смена не закрыта, мы можем либо просто предупредить,
// либо установить Отказ = Истина, чтобы не дать закрыть программу
ТекстВопроса = "Внимание! Кассовая смена не закрыта. Закрыть смену перед выходом?";
// Логика обработки ответа пользователя через ОписаниеОповещения
КонецЕсли;
КонецЕсли;
КонецПроцедуры
Разберем подробнее проблему асинхронности. В 1С:ERP 2.4, работающей в режиме "Запрет модальных вызовов", обычная функция Вопрос() или Предупреждение() работать не будет. Процедура ПередЗавершениемРаботыСистемы завершается сразу после выполнения кода, не дожидаясь ответа пользователя из диалогового окна.
Чтобы корректно реализовать остановку закрытия, нам нужно использовать следующий подход:
ПередЗавершениемРаботыСистемы проверяем условие (например, наличие открытой смены).Отказ = Истина.ПоказатьВопрос с использованием ОписаниеОповещения.ЗавершитьРаботуСистемы(Ложь), чтобы закрыть базу без повторной проверки.Проанализируем ситуацию, когда уведомление нужно не всем, а только конкретным сотрудникам. Использовать жесткую привязку к имени пользователя (строкой) — плохая практика, так как имя может измениться. Рассмотрим более гибкие варианты:
Вариант А: Использование ролей. Это самый правильный метод с точки зрения архитектуры. Создадим в расширении пустую роль УведомлятьОЗакрытииСмены и назначим её нужным пользователям.
Функция НужноВыводитьНапоминание()
Возврат РольДоступна("УведомлятьОЗакрытииСмены");
КонецФункции
Вариант Б: Дополнительные реквизиты. В справочнике "Пользователи" можно добавить дополнительный реквизит типа Булево. Это позволит администратору системы включать и выключать уведомление прямо в режиме "1С:Предприятие" без помощи программиста.
Выясним, как программно определить, нужно ли вообще выводить сообщение. В ERP информация о сменах хранится в регистре сведений КассовыеСмены. Нам нужно проверить записи со статусом Открыта для текущего пользователя или текущего рабочего места.
Пример функции для проверки (выполняется на сервере):
&НаСервере
Функция ЕстьОткрытыеКассовыеСмены()
Запрос = Новый Запрос;
Запрос.Текст =
"ВЫБРАТЬ ПЕРВЫЕ 1
| КассовыеСмены.Ссылка
|ИЗ
| Документ.КассоваяСмена КАК КассовыеСмены
|ГДЕ
| КассовыеСмены.Статус = ЗНАЧЕНИЕ(Перечисление.СтатусыКассовыхСмен.Открыта)
| И КассовыеСмены.Менеджер = &ТекущийПользователь";
Запрос.УстановитьПараметр("ТекущийПользователь", ПараметрыСеанса.ТекущийПользователь);
Результат = Запрос.Выполнить();
Возврат Не Результат.Пустой();
КонецФункции
Если работа с глобальным модулем через расширение кажется избыточной или вызывает конфликты с другими доработками, существует альтернативный способ. Мы можем создать в расширении общую форму, которая будет программно открываться при запуске системы в невидимом режиме.
Рассмотрим пошагово этот метод:
Расш1_КонтрольЗавершения).ПриНачалеРаботыСистемы прописываем открытие этой формы: ОткрытьФорму("ОбщаяФорма.Расш1_КонтрольЗавершения", , , Ложь);.ПередЗакрытием.Поскольку при закрытии программы 1С пытается закрыть все открытые окна, событие ПередЗакрытием в нашей скрытой форме сработает гарантированно. В нем мы можем задать вопрос пользователю и, если нужно, установить Отказ = Истина для отмены закрытия всей программы.
Рассмотрим ситуации, когда данные методы могут не сработать. Если пользователь выключает компьютер через кнопку "Завершить работу" в Windows, операционная система может принудительно завершить процесс 1cv8.exe. В этом случае обработчики 1С могут не успеть выполниться или их окна будут автоматически закрыты системой. Поэтому важно донести до пользователей, что штатный выход из программы — залог корректного учета.
Также стоит помнить, что в 1С:ERP активно используется БСП (Библиотека стандартных подсистем). Перед написанием своего велосипеда, проанализируйте общий модуль СтандартныеПодсистемыКлиент. Возможно, в вашей версии конфигурации уже внедрены механизмы проверки перед выходом, в которые можно интегрироваться через &После или &Вместо, добавив свое условие в массив проверок.
Подведем итог: наиболее надежным и современным способом является расширение модуля управляемого приложения с использованием асинхронных диалогов и проверкой ролей пользователя. Это сохраняет чистоту конфигурации и обеспечивает стабильную работу системы.