Как реализовать подробный аудит изменений в 1С 7.7: альтернативы штатному журналу регистрации

Программист 1С v7.7 IT и автоматизация бизнеса
← На главную

Штатный журнал регистрации в 1С:Предприятие 7.7 имеет ряд существенных ограничений. Он фиксирует лишь факт изменения объекта, но не дает детальной информации о том, какой именно реквизит был изменен, какое значение было «до» и какое стало «после». Кроме того, при интенсивной работе файл .log быстро разрастается, что приводит к критическим тормозам системы. Разберем, как можно реализовать полноценный аудит изменений, который будет отвечать требованиям безопасности и производительности.

Метод 1: Использование программных процедур в коде конфигурации

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

Рассмотрим пример реализации структуры такой процедуры. Для этого нам потребуется создать в Глобальном модуле функции, которые будут сравнивать текущее состояние объекта с тем, что уже записано в базе данных. Посмотрим на пример кода, который может быть использован для протоколирования:


Процедура глЗаписатьПротоколИзмененийДокумента(Конт, ВарТабл = 0) Экспорт
    // Конт - контекст документа, который мы проверяем
    // Проверяем, является ли документ новым
    Если Конт.Выбран() = 0 Тогда
        Возврат;
    КонецЕсли;
    
    // Создаем объект для чтения старых данных из базы
    СтарыйОбъект = СоздатьОбъект("Документ." + Конт.Вид());
    СтарыйОбъект.НайтиДокумент(Конт.ТекущийДокумент());
    
    // Перебираем реквизиты и сравниваем значения
    Для Номер = 1 По Метаданные.Документ(Конт.Вид()).РеквизитШапки() Цикл
        ИмяРеквизита = Метаданные.Документ(Конт.Вид()).РеквизитШапки(Номер).Идентификатор;
        Если Конт.ПолучитьАтрибут(ИмяРеквизита) <> СтарыйОбъект.ПолучитьАтрибут(ИмяРеквизита) Тогда
            // Записываем изменение в отдельный справочник или SQL-таблицу
            глЗаписатьВЛог(Конт.ТекущийДокумент(), ИмяРеквизита, СтарыйОбъект.ПолучитьАтрибут(ИмяРеквизита), Конт.ПолучитьАтрибут(ИмяРеквизита));
        КонецЕсли;
    КонецЦикла;
КонецПроцедуры

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

Метод 2: Использование SQL-триггеров (для версии SQL)

Если ваша база работает под управлением MS SQL Server, мы можем задействовать мощь самой СУБД. Это наиболее производительный метод, так как нагрузка по отслеживанию изменений перекладывается с уровня приложения 1С на уровень сервера базы данных.

Проанализируем преимущества этого подхода:

  1. Производительность: SQL-триггеры работают чрезвычайно быстро и не блокируют работу пользователей так, как это делает запись в текстовый файл .log.
  2. Надежность: Обойти триггер практически невозможно, даже если изменения вносятся прямыми SQL-запросами в обход интерфейса 1С.
  3. Детализация: Триггер имеет доступ к виртуальным таблицам inserted и deleted, что позволяет легко получить значения до и после транзакции.

Для реализации этого метода создается отдельная таблица в базе данных (например, AuditTrail), куда триггер будет записывать идентификатор объекта (ID), имя колонки, старое и новое значение. Выясним причину, почему это не делают все: для расшифровки имен таблиц (SC*, DH*) и реквизитов вам потребуется знание структуры 1cv7.dd или использование внешних компонент для получения метаданных.

Метод 3: Использование внешних компонент (FormEx и 1С++)

Для расширения возможностей платформы 7.7 часто применяются компоненты FormEx и 1С++. Рассмотрим подробнее, как они помогают в решении нашей задачи.

С помощью FormEx можно перехватывать события, которые недоступны в штатном режиме. Например, мы можем фиксировать не только запись, но и просто факт открытия формы пользователем или изменение конкретного поля на форме еще до момента записи. Это позволяет понять, кто «просто любопытствовал» и просматривал конфиденциальные данные.

Компонента 1С++ позволяет выполнять прямые SQL-запросы к базе данных. Разберем по шагам, как организовать просмотр накопленных логов:

  1. Данные аудита сохраняются в отдельную таблицу SQL (через триггеры или код 1С).
  2. В интерфейсе 1С создается обработка «Анализ изменений».
  3. С помощью объекта ODBCRecordset из 1С++ данные мгновенно извлекаются из SQL-таблицы и выводятся пользователю в виде удобного отчета.

Это избавляет от необходимости сканировать огромные текстовые файлы журнала регистрации, что в 1С 7.7 обычно занимает очень много времени.

Метод 4: Полноценное версионирование объектов

Если задача стоит не просто «кто поменял», а «нужна возможность откатиться к старой версии», мы должны реализовать систему версионирования. Разберем этот механизм. При каждой записи документа или справочника мы сохраняем полную копию его состояния. Чтобы не раздувать базу данных, данные можно сохранять в формате XML или сжатой строки.

Посмотрим на пример логики сохранения версии:


Процедура глСохранитьВерсиюОбъекта(Конт) Экспорт
    // Преобразуем все реквизиты объекта в строку (например, через ЗначениеВСтрокуВнутр)
    ТекущееСостояние = ЗначениеВСтрокуВнутр(Конт.ТекущийОбъект());
    
    // Записываем в специальный справочник "ВерсииОбъектов"
    СпрВерсии = СоздатьОбъект("Справочник.ВерсииОбъектов");
    СпрВерсии.Новый();
    СпрВерсии.Объект = Конт.ТекущийДокумент();
    СпрВерсии.ДатаИзменения = ТекущаяДата();
    СпрВерсии.Автор = ИмяПользователя();
    СпрВерсии.Данные = ТекущееСостояние;
    СпрВерсии.Записать();
КонецПроцедуры

Такой подход позволяет в любой момент открыть старую версию документа и сравнить ее с текущей с помощью специализированной обработки сравнения (Diff), выделяя цветом измененные строки и реквизиты.

Рекомендации по оптимизации

При внедрении системы аудита важно соблюдать баланс между детальностью логов и скоростью работы. Рассмотрим несколько советов:

В заключение отметим, что выбор конкретного метода зависит от масштаба базы и квалификации администратора. Для небольших баз достаточно программных процедур в коде 1С, тогда как для крупных высоконагруженных систем единственным верным решением будет использование SQL-триггеров в связке с 1С++.

← На главную