- Справочники данных Контрагенты, КонтактныеЛица, служебный справочник ХранимыеРеквизиты;
- Документ ОплатаПокупателя;
- Периодический регистр сведений ИсторияРеквизитов.
Реквизиты справочников данных и документа создаем по своему усмотрению. Служебный справочник ХранимыеРеквизиты дополнительных реквизитов не имеет, иерархия групп и элементов, ограничение по количеству уровней - 2. Заполняем его следующим образом: наименование группы представляет собой полное имя метаданных объекта (например, "Справочник.Контрагенты"), в наименовании элементов содержатся имена реквизитов объектов идентично именам в конфигураторе. Это позволяет организовать выборочную фиксацию истории реквизитов конкретных объектов.
Создаем регистр сведений ИсторияРеквизитов, периодический, в пределах секунды. Тип для реквизита "Объект" - составной: ДокументСсылка, СправочникСсылка, для "Реквизит" - СправочникСсылка.ХранимыеРеквизиты, "Значение" - составной: Булево, Строка, Дата, Число, ЛюбаяСсылка.
Весь код вынесен в общий модуль ИсторияРеквизитов:
Процедура ОбновитьИсторию(Ссылка, Период = Неопределено) Экспорт мТекущие = ПолучитьРеквизиты(Ссылка, Период); Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ХранимыеРеквизиты.Ссылка, | ХранимыеРеквизиты.Наименование |ИЗ | Справочник.ХранимыеРеквизиты КАК ХранимыеРеквизиты |ГДЕ | НЕ ХранимыеРеквизиты.ПометкаУдаления | И ХранимыеРеквизиты.Родитель.Наименование = &Родитель |АВТОУПОРЯДОЧИВАНИЕ"; Запрос.УстановитьПараметр("Родитель", Ссылка.Метаданные().ПолноеИмя()); Результат = Запрос.Выполнить(); Если Результат.Пустой() Тогда Возврат; КонецЕсли; Выборка = Результат.Выбрать(); ПериодЗаписи = ТекущаяДата(); мНабор = РегистрыСведений.ИсторияРеквизитов.СоздатьНаборЗаписей(); мНабор.Отбор.Объект.Установить(Ссылка); мНабор.Отбор.Период.Установить(ПериодЗаписи); мНабор.Прочитать(); Пока Выборка.Следующий() Цикл //контроль изменения значений реквизитов Если мТекущие[Выборка.Ссылка] = Ссылка[Выборка.Наименование] Тогда Продолжить; КонецЕсли; мЗапись = мНабор.Добавить(); мЗапись.Период = ПериодЗаписи; мЗапись.Объект = Ссылка; мЗапись.Реквизит = Выборка.Ссылка; мЗапись.Значение = Ссылка[Выборка.Наименование]; КонецЦикла; Если мНабор.Количество() = 0 Тогда Возврат; КонецЕсли; мНабор.Записать(); КонецПроцедуры Функция ПолучитьРеквизиты(Ссылка, Период = Неопределено) Экспорт Запрос = Новый Запрос; Запрос.Текст = "ВЫБРАТЬ | ИсторияРеквизитовСрезПоследних.Реквизит КАК Реквизит, | ИсторияРеквизитовСрезПоследних.Значение |ИЗ | РегистрСведений.ИсторияРеквизитов.СрезПоследних(&Период, Объект = &Ссылка) КАК ИсторияРеквизитовСрезПоследних | |УПОРЯДОЧИТЬ ПО | Реквизит |АВТОУПОРЯДОЧИВАНИЕ"; Запрос.УстановитьПараметр("Ссылка", Ссылка); Запрос.УстановитьПараметр("Период", Период); мРеквизиты = Новый Соответствие; Результат = Запрос.Выполнить().Выбрать(); Пока Результат.Следующий() Цикл мРеквизиты.Вставить(Результат.Реквизит, Результат.Значение); КонецЦикла; Возврат мРеквизиты; КонецФункции //обработка подписки на событие ЗаписьИстории Процедура ЗаписьИсторииПриЗаписи(Источник, Отказ) Экспорт ОбновитьИсторию(Источник.Ссылка); КонецПроцедурыВ конце оформляем подписку на событие ПриЗаписи.
Теперь остается запустить и протестировать, создавая новые элементы справочников и документы и внося в них изменения. В списке регистра сведений можно увидеть историю изменений значений реквизитов этих объектов.
Так же можно завести справочник пользователей и дополнительно фиксировать автора изменений.
Комментариев нет:
Отправить комментарий