При сопровождении и доработке конфигураций на платформе 1С:Предприятие 7.7 часто возникает задача логирования действий пользователей, аудита открываемых данных или реализации дополнительного контроля доступа. Внедрять вызовы функций в модуль формы каждого справочника, документа или отчета вручную — трудоемкая задача, которая усложняет дальнейшее обновление типовой конфигурации.
Штатный функционал платформы 1С 7.7 не предоставляет глобальных событий открытия или закрытия форм. Разберем по шагам, как решить эту задачу централизованно с помощью внешних компонент FormEx и 1C++.
Внешняя компонента FormEx расширяет объектную модель интерфейса 1С 7.7 и добавляет глобальные обработчики событий, которые объявляются в Глобальном модуле конфигурации.
Рассмотрим основные предопределенные процедуры FormEx, позволяющие перехватывать работу с окнами и объектами:
Для перехвата открытия любых окон (включая справочники, документы, отчеты и обработки) используется процедура ПослеОткрытия().
Процедура ПослеОткрытия(Контекст)
// Определяем тип открытого объекта через функции FormEx
Сервис = СоздатьОбъект("Сервис");
ТипОбъекта = Сервис.ТипОбъекта(Контекст);
ПолныйТип = Сервис.ПолныйТипОбъекта(Контекст);
Сообщить("Открыта форма: " + ПолныйТип + " (Тип: " + ТипОбъекта + ")");
КонецПроцедуры
Если требуется зафиксировать факт открытия объекта на редактирование или получение им блокировки, применяется событие ПриНачалеБлокировкиОбъекта().
Процедура ПриНачалеБлокировкиОбъекта(Объект)
// В параметр передается сам блокируемый объект базы данных
Сообщить("Заблокирован объект: " + Объект);
КонецПроцедуры
Для фиксации закрытия окна формы используется процедура ПослеЗакрытия(). В неё передается контекст закрываемого окна. Чтобы понять, какой именно объект был закрыт, используем методы ТипОбъекта и ПолныйТипОбъекта.
Процедура ПослеЗакрытия(Контекст)
Сервис = СоздатьОбъект("Сервис");
ТипКонт = Сервис.ТипОбъекта(Контекст);
ПолныйТипКонт = Сервис.ПолныйТипОбъекта(Контекст);
Если ТипКонт = "Документ" Тогда
Сообщить("Закрыт документ вида: " + ПолныйТипКонт);
ИначеЕсли ТипКонт = "Справочник" Тогда
Сообщить("Закрыт справочник: " + ПолныйТипКонт);
КонецЕсли;
КонецПроцедуры
Проанализируем ситуацию, когда необходимо не просто отследить факт закрытия окна, но и понять, сохранил ли пользователь изменения (нажав «ОК») или закрыл форму без сохранения (через «Отмена», клавишу Esc или системную кнопку закрытия).
В момент вызова ПослеЗакрытия контекст формы уже завершил работу, и штатно определить факт сохранения невозможно. Для решения этой задачи оптимально подходит класс Перехватчик из состава библиотеки 1С++.
Разберем алгоритм работы с перехватчиком:
Перехватчик позволяет централизованно внедрить обработчик в системное событие формы ПриЗаписи для всех документов и справочников.Событие_ПриЗаписи() перехватчика. В ней мы регистрируем ссылку/идентификатор объекта в глобальном списке сохраненных объектов.ПослеЗакрытия() проверяем, числится ли данный объект в списке сохраненных, выполняем целевое действие и очищаем признак из списка.
// Пример логики внутри класса Перехватчик (1С++)
Процедура Событие_ПриЗаписи(Контекст, Отказ) Экспорт
// Пользователь нажал кнопку сохранения в форме
гСписокСохраненных.Установить(Контекст.ТекущийДокумент(), 1);
КонецПроцедуры
При проектировании глобального аудита и контроля форм учитываем следующие особенности платформы 1С 7.7:
ПослеОткрытия, ПослеЗакрытия и перехватываемые события форм срабатывают исключительно при интерактивной работе пользователя в интерфейсе. Если объект изменяется или создается программно через метод Записать(), интерфейсные события не возникают._1SJOURN, таблицы справочников) можно реализовать триггерами СУБД, что гарантирует фиксацию изменений вне зависимости от способа записи.