Имя: Пароль:
1C
 
Быстрое сравнение объектов
0 Dimon1C
 
29.10.25
10:25
Добрый день. Подскажите, как можно быстро сравнить ПередЗаписью объекта изменился ли объект (хотя бы один реквизит)?
Пока вижу 2 подхода:
1. Сравнить все реквизиты (по метаданным)
2. Сериализация в XML (функция ЗаписатьXML) и потом сравнение

Может что еще есть?
1 Garykom
 
гуру
29.10.25
10:32
ЗаписьFastInfoset или ЗаписьJSON будет быстрее
2 Ненавижу 1С
 
гуру
29.10.25
10:33
(0) может достаточно проверить Модифицированность? хотя конечно это не совсем то. Еще ВерсияДанных
3 Dimon1C
 
29.10.25
10:42
(2) Версия данных меняется даже если никакой реквизит не изменился.
4 Garykom
 
гуру
29.10.25
10:44
Тут главный вопрос зачем это сравнивать?
Для чего это требуется?
5 Ильф
 
29.10.25
10:49
(4) что бы не записывать, например
пользователи постоянно открывают "посмотреть" и закрывают через "Провести закрыть"
6 Garykom
 
гуру
29.10.25
10:51
(5) В этом случае прекрасно работает Модифицированность
7 Dimon1C
 
29.10.25
10:51
(4) Для регистрации обмена со сторонними ИС
8 Garykom
 
гуру
29.10.25
10:53
(7) Не страдать фигней и регистрировать к обмену
Или можно получить дикие тормоза в некоторых случаях

Дешевле лишний раз отправить чем отличать что поменялось и надо ли отправлять
9 arsik
 
гуру
29.10.25
10:58
(7) Посмотри как это работает в БСП ВерсионированиеОбъектов.
Нам наоборот пришлось уйти от стандартной схемы, т.к. в документах есть общий реквизит "ДатаОперации" и другие, незначащие - и у нас писалось даже и при перезаписи объекта.
Функция ВерсияОтличаетсяОтРанееЗаписанной(Объект)
	
	ТекстЗапроса = 
	"ВЫБРАТЬ ПЕРВЫЕ 1
	|	ВерсииОбъектов.КонтрольнаяСумма
	|ИЗ
	|	РегистрСведений.ВерсииОбъектов КАК ВерсииОбъектов
	|ГДЕ
	|	ВерсииОбъектов.Объект = &Объект
	|
	|УПОРЯДОЧИТЬ ПО
	|	ВерсииОбъектов.НомерВерсии УБЫВ";
	
	Запрос = Новый Запрос(ТекстЗапроса);
	Запрос.УстановитьПараметр("Объект", Объект.Ссылка);
	Выборка = Запрос.Выполнить().Выбрать();
	Если Выборка.Следующий() И Не ПустаяСтрока(Выборка.КонтрольнаяСумма) Тогда
		Возврат Выборка.КонтрольнаяСумма <> КонтрольнаяСумма(ДанныеДляХранения(Объект));
	КонецЕсли;
	
	Возврат Объект.ЭтоНовый() Или КонтрольнаяСумма(ДанныеДляХранения(Объект)) <> КонтрольнаяСумма(ДанныеДляХранения(Объект.Ссылка.ПолучитьОбъект()));
	
КонецФункции

Функция КонтрольнаяСумма(Данные) Экспорт
	ХешированиеДанных = Новый ХешированиеДанных(ХешФункция.MD5);
	
	Если ТипЗнч(Данные) = Тип("Структура") Тогда
		ХешированиеДанных.Добавить(Данные.Объект);
		Если Данные.Свойство("ДополнительныеРеквизиты") Тогда
			ХешированиеДанных.Добавить(ОбщегоНазначения.ЗначениеВСтрокуXML(Данные.ДополнительныеРеквизиты));
		КонецЕсли;
	Иначе
		ХешированиеДанных.Добавить(Данные);
	КонецЕсли;
	
	Возврат СтрЗаменить(ХешированиеДанных.ХешСумма, " ", "");
КонецФункции


(8) Да с чего тормоза. Версионирование во всех типовых работает и норм.
10 Garykom
 
гуру
29.10.25
10:59
Если есть случаи лишних массовых отправок - надо решать их первопричину
Например если юзеры наслаждаются перепроведением старых документов и оно пытается снова улетать в обмен - надо решать эту проблему, а не следствие
11 Garykom
 
гуру
29.10.25
11:01
(9) Включение версионирования в типовых резко их тормозит
И да там сохраняются версии через ЗаписьFastInfoset
12 arsik
 
гуру
29.10.25
11:16
(11) так я и не против фастинфосета
13 H A D G E H O G s
 
29.10.25
11:38
(0) Храни Хэш и сравнивай с ним.
14 Garykom
 
гуру
29.10.25
11:44
(13) В том и вопрос каким образом лучше получать хеш

Вот в (9) например функция ДанныеДляХранения() не описана
15 Garykom
 
гуру
29.10.25
11:51
Если конфа типовая ERP/КА - то там в обмене-бесшовке с ДО уже есть требуемый функционал с Хешем
Хранением его в отдельном РС и сравнением перед выгрузкой в регзадании
Но в очередь (регистрация в плане обмена) просто при каждой записи помещается, без лишних извратов
Программист всегда исправляет последнюю ошибку.