В данной обработке приведен способ расчета контрольной суммы объекта базы данных 1С. При любом изменении данных объекта, контрольная сумма меняется. Вариант расчета контрольной суммы меняем программно. В моем случае CRC32 как раз подходит - это число.
Это может быть полезно:
- При сравнении документов в различных базах, и не только РИБ
- В механизме определения, изменен ли объект в журналах изменений.
- В тех областях, о которых я еще не знаю.
Вот сам код обработки:
&НаСервере
Процедура Рассчитать()
Объект=Ссылка.ПолучитьОбъект();
ПолучитьХешОбъекта(Объект);
КонецПроцедуры
&НаСервере
Процедура ПолучитьХешОбъекта(Объект)
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML,Объект);
ДанныеСтрока=ЗаписьXML.Закрыть();
Хеш=Новый ХешированиеДанных(ХешФункция.CRC32);
Хеш.Добавить(ДанныеСтрока);
Сообщить(Хеш.ХешСумма);
КонецПроцедуры
Обновлено от 03.08.2016! Если нужно получить контрольную сумму ссылочного объекта, то код выше это делает. Если нужно получить контрольную сумму записей регистров сведений, например, то лучше использовать либо наборы записей (медленный способ), либо получить данные записей запросом, и каждую запись преобразовать в структуру, и уже ее использовать для расчета контрольной суммы (быстрый способ).
Вот примерный код:
СтрокаИзмерений="";
Для каждого Измерение Из ОбъектМетаданных.Измерения Цикл
СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),Измерение.Имя,","+Измерение.Имя);
КонецЦикла;
Если ОбъектМетаданных.ПериодичностьРегистраСведений<>Метаданные.СвойстваОбъектов.ПериодичностьРегистраСведений.Непериодический Тогда
СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),"Период",",Период");
КонецЕсли;
Для каждого Ресурс Из ОбъектМетаданных.Ресурсы Цикл
СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),Ресурс.Имя,","+Ресурс.Имя);
КонецЦикла;
Для каждого Реквизит Из ОбъектМетаданных.Реквизиты Цикл
СтрокаИзмерений=СтрокаИзмерений+?(ПустаяСтрока(СтрокаИзмерений),Реквизит.Имя,","+Реквизит.Имя);
КонецЦикла;
СтруктураДанных=Новый Структура(СтрокаИзмерений);
Выборка=РегистрыСведений[Имя].Выбрать();
Пока Выборка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(СтруктураДанных,Выборка);
ХешСумма=ПолучитьХешОбъекта(СтруктураДанных);
КонецЦикла;
Обновлено от 09.08.2016! Как показала практика, применение способа ПолучитьОбъект() для расчета контрольной суммы не всегда оптимально (если много объектов и немного оперативной памяти) и приводит к нехватке памяти т.к. полученные объекты не удаляются из оперативной памяти, а остаются там до окончания процесса. Код вида "Объект=Неопределено" никогда не помогает!
Был найден обходной путь, через запрос. При этом память не забивается, а скорость даже возросла.
Вот пример кода для документов:
Запрос = Новый Запрос;
Запрос.Текст ="ВЫБРАТЬ * ИЗ "+ОбъектМетаданных.ПолноеИмя();
Результат=Запрос.Выполнить();
Выборка=Результат.Выбрать();
СтрокаРеквизитов="";
Для каждого Колонка Из Результат.Колонки Цикл
Если Колонка.Имя="ВерсияДанных" ИЛИ Колонка.Имя="МоментВремени" ИЛИ Колонка.Имя="Предсталение" Тогда Продолжить; КонецЕсли;
СтрокаРеквизитов=СтрокаРеквизитов+?(ПустаяСтрока(СтрокаРеквизитов),"",",")+Колонка.Имя;
КонецЦикла;
СтруктураОбъекта=Новый Структура(СтрокаРеквизитов);
Пока Выборка.Следующий() Цикл
ЗаполнитьЗначенияСвойств(СтруктураОбъекта,Выборка);
Для каждого ТабЧасть Из ОбъектМетаданных.ТабличныеЧасти Цикл
СтруктураОбъекта.Вставить(ТабЧасть.Имя,Выборка[ТабЧасть.Имя].Выгрузить());
КонецЦикла;
ХешСумма=ПолучитьХешОбъекта(СтруктураОбъекта);
КонецЦикла;
Функция ПолучитьХешОбъекта(Объект)
ЗаписьXML = Новый ЗаписьXML;
ЗаписьXML.УстановитьСтроку();
СериализаторXDTO.ЗаписатьXML(ЗаписьXML,Объект);
ДанныеСтрока=ЗаписьXML.Закрыть();
Хеш=Новый ХешированиеДанных(ХешФункция.CRC32);
Хеш.Добавить(ДанныеСтрока);
Возврат Хеш.ХешСумма;
КонецФункции;