При разработке самописных конфигураций или доработке типовых решений часто возникает необходимость отслеживать, кто, когда и как менял реквизиты объектов (справочников, документов и др.). Рассмотрим основные архитектурные варианты решения этой задачи, их преимущества, недостаточную сторону каждого подхода и примеры программной реализации.
Если в вашей конфигурации используется Библиотека Стандартных Подсистем (БСП), наиболее правильным и быстрым решением будет подключение встроенной подсистемы версионирования. Разберем основные плюсы этого подхода:
РегистрСведений.ВерсииОбъектов.Для подключения достаточно включить нужный справочник в состав определяемого типа ОбъектВерсионирования и настроить правила в пользовательском режиме.
В современных версиях платформы 1С:Предприятие 8.3 присутствует штатный механизм ядра СУБД — ИсторияДанных. Разберем, чем он отличается от прикладного версионирования:
ИсторияДанных можно получать разницу версий и восстанавливать объект на нужный момент времени с помощью метода СформироватьПоВерсии().Включить историю данных для справочника можно прямо в конфигураторе, установив свойство объекта метаданных ИсторияДанных в значение Использовать.
Если конфигурация полностью самописная и использование БСП не планируется, стандартным прикладным способом является создание периодического регистра сведений (например, ИсторияИзмененийСправочников). Проанализируем возможные варианты структуры регистра:
Объект (Ссылка), Период.
ДанныеВерсии (тип ХранилищеЗначения), Пользователь (СправочникСсылка.Пользователи).
Объект, Период, ИмяРеквизита (Строка).
ЗначениеБыло (Строка/ЛюбаяСсылка), ЗначениеСтало.
Разберем пример создания дампа объекта в XML-файл или строковый поток при его записи. Посмотрим, как выгрузить текущий объект в формат XML прямо из модуля объекта или формы:
// Пример записи объекта в XML-файл при возникновении события или исключения
СтрокаСоединенияИнформационнойБазы = СтрокаСоединенияИнформационнойБазы();
ПутьКБД = Сред(СтрокаСоединенияИнформационнойБазы, 7, СтрДлина(СтрокаСоединенияИнформационнойБазы) - 8);
ЗаписьXML = Новый ЗаписьXML();
ЗаписьXML.ОткрытьФайл(ПутьКБД + "\" + СокрЛП(ТипЗнч(Объект)) + Объект.Код + ".xml");
ЗаписьXML.ЗаписатьНачалоЭлемента("Root");
// Сериализуем объект 1С целиком
ВыгружаемыйОбъект = Объект;
ЗаписатьXML(ЗаписьXML, ВыгружаемыйОбъект);
ЗаписьXML.ЗаписатьКонецЭлемента();
ЗаписьXML.Закрыть();
Для обратного чтения и восстановление данных из XML-файла используется следующий алгоритм:
// Чтение XML и загрузка объекта в базу
Файл = Новый ЧтениеXML();
Файл.ОткрытьФайл(ИмяФайла);
Пока Файл.Прочитать() Цикл
ОбъектЗагрузки = ПрочитатьXML(Файл);
ОбъектЗагрузки.Записать();
КонецЦикла;
Файл.Закрыть();
Важное предупреждение: Использовать чистую сериализацию ЗаписатьXML / ПрочитатьXML для долговременного хранения истории следует с осторожностью. При изменении структуры метаданных (например, удалении или переименовании реквизитов справочника) старые файлы XML могут перестать быть валидными для чтения.
При реализации собственного механизма отслеживания изменений проанализируем ключевые технические нюансы:
ХранилищеЗначения, обязательно используйте сжатие (параметр СжатиеДанных.ОптимизацияСжатия), чтобы предотвратить раздувание размера базы СУБД.