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