четверг, 9 апреля 2015 г.

Журналирование документов без журнала регистрации

Бываю случаи, при которых искать что-то по журналу регистрации слишком долго и становится невозможным, а сам журнал регистрации при этом значительно тормозит. Как альтернатива стандартному платформенному журналу пришло решение вести учет изменений в самой базе, в отдельных таблицах по каждому объекту.
Например, для документа я решил создать табличную часть "Log".
В МодулеОбъекта этого документа пропишем следующие процедуры:
Процедура ЗаписатьИзмененияВЛог(ТабЧасть)
    Если ЭтоНовый() Тогда
        ДобавитьЗаписьВ_ТЧ_Log(ТабЧасть, ТекущаяДата(), "", "", "", ПараметрыСеанса.ТекущийПользователь, Истина, Ложь);
    Иначе
        Для Каждого Реквизит ИЗ Метаданные().Реквизиты Цикл
            ИмяРеквизита = Реквизит.Имя;
            ЗначениеРеквизита = "";
            СтрокаВыполнения = "ЗначениеРеквизита = " + ИмяРеквизита;
            Выполнить(СтрокаВыполнения);
            ЗначениеРеквизитаИзСсылки = "";
            СтрокаВыполнения = "ЗначениеРеквизитаИзСсылки = Ссылка." + ИмяРеквизита;
            Выполнить(СтрокаВыполнения);
            Если ЗначениеРеквизита <> ЗначениеРеквизитаИзСсылки Тогда
                ДобавитьЗаписьВ_ТЧ_Log(ТабЧасть, ТекущаяДата(), ИмяРеквизита, Строка(ЗначениеРеквизитаИзСсылки), Строка(ЗначениеРеквизита), ПараметрыСеанса.ТекущийПользователь, Ложь, Ложь);
            КонецЕсли;
        КонецЦикла;
        Если ПометкаУдаления <> Ссылка.ПометкаУдаления Тогда
            ДобавитьЗаписьВ_ТЧ_Log(ТабЧасть, ТекущаяДата(), "", "", "", ПараметрыСеанса.ТекущийПользователь, Ложь, ПометкаУдаления);
        КонецЕсли;
    КонецЕсли;
    //По табличным частям
        Для Каждого ТЧ ИЗ Метаданные().ТабличныеЧасти Цикл
            ИмяТЧ = ТЧ.Имя;
            Если ИмяТЧ = "Log" Тогда Продолжить; КонецЕсли;
            ТЗИзмененная = Новый ТаблицаЗначений;
            ТЗСсылки = Новый ТаблицаЗначений;
            СтрокаВыполнения = "ТЗИзмененная = " + ИмяТЧ + ".Выгрузить(); ТЗСсылки = Ссылка." + ИмяТЧ + ".Выгрузить()" ;
            Выполнить(СтрокаВыполнения);
            КолНовыхСтрок = ТЗИзмененная.Количество();
            КолСтарыхСтрок = ТЗСсылки.Количество();
            ИндексПоследнейСтрокиТЗСсылки = КолСтарыхСтрок - 1;
            Для Каждого СтрИзмененная ИЗ ТЗИзмененная Цикл
                ИндексСтроки = СтрИзмененная.НомерСтроки-1;
                Если ИндексСтроки <= ИндексПоследнейСтрокиТЗСсылки Тогда
                    СтрТЗСсылки = ТЗСсылки[ИндексСтроки];
                КонецЕсли;
                Для Каждого Колонка ИЗ ТЗИзмененная.Колонки Цикл
                    ИмяКолонки = Колонка.Имя;
                    Если ИмяКолонки = "НомерСтроки" Тогда Продолжить; КонецЕсли;
                    ИмяРеквизита = ИмяТЧ+"."+ИмяКолонки+"."+СтрИзмененная.НомерСтроки;
                    ЗначениеДо = "";
                    ЗначениеПосле = "";
                    СтрокаВыполнения = "ЗначениеПосле = СтрИзмененная." + ИмяКолонки;
                    Выполнить(СтрокаВыполнения);
                    Если КолСтарыхСтрок = 0 Тогда
                        ДобавитьЗаписьВ_ТЧ_Log(ТабЧасть, ТекущаяДата(), ИмяРеквизита,  Строка(ЗначениеДо),  Строка(ЗначениеПосле), ПараметрыСеанса.ТекущийПользователь, Истина, Ложь);
                        Продолжить;
                    КонецЕсли;
                    СтрокаВыполнения = "ЗначениеДо = СтрТЗСсылки." + ИмяКолонки;
                    Выполнить(СтрокаВыполнения);
                    Если ЗначениеДо <> ЗначениеПосле Тогда
                        ДобавитьЗаписьВ_ТЧ_Log(ТабЧасть, ТекущаяДата(), ИмяРеквизита,  Строка(ЗначениеДо),  Строка(ЗначениеПосле), ПараметрыСеанса.ТекущийПользователь, Ложь, Ложь);
                    КонецЕсли;
                КонецЦикла;
            КонецЦикла;
        КонецЦикла;
        //Освобождаем память
        ТЗИзмененная = Неопределено;
        ТЗСсылки = Неопределено;
КонецПроцедуры

Процедура ДобавитьЗаписьВ_ТЧ_Log(ТабЧасть, пДатаИзменения, пИмяРеквизита, пЗначениеДо, пЗначениеПосле, пОтветственный, пСоздание, пУдаление)
    СтрИстории = ТабЧасть.Добавить();
    СтрИстории.ДатаИзменения = пДатаИзменения;
    СтрИстории.Реквизит = пИмяРеквизита;
    СтрИстории.ЗначениеДо = пЗначениеДо;
    СтрИстории.ЗначениеПосле = пЗначениеПосле;
    СтрИстории.Ответственный = пОтветственный;
    СтрИстории.Создание = пСоздание;
    СтрИстории.Удаление = пУдаление;
КонецПроцедуры


И вызываем выполнение в Процедуре ПередЗаписью:
Процедура ПередЗаписью(Отказ)
    ЗаписатьИзмененияВЛог(Log);
КонецПроцедуры







Комментариев нет:

Отправить комментарий