gifts2017

Проверка идентичности баз 1с7 по OLE

Опубликовал Осипов Сергей (fixin) в раздел Администрирование - Системное

Обработка позволяет проверить идентичность двух баз по OLE. Универсальная.
Удобна, если сравниваются распределенные базы или база с архивом.

В обработке нужно указать период, за который сравниваются документы, после чего происходит подключение по OLE к другой базе, и сравниваются документы за указанный период в обоих базах. При подключении по OLE запрашивается база и пароль для сравнения у пользователя.

Документы и справочники синхронизируются по внутреннему значению идентификатора.

Сравниваются только документы и справочники, на которые есть ссылки из документов.

Обработка не только сравнивает существующие в обоих базах документы, но и умно находит те документы, которые есть только в одной из баз.

В результате в окно сообщений выдается протокол вида:

В текущей базе не найден документ: ПриходнаяНакладная №  РН-000889 от 11.10.2008
В текущей базе не найден документ: РасходнаяНакладная №  РН-000178 от 12.09.2005
Документы не идентичны: ПриходнаяНакладная №  ПН-002234 от 01.12.2009
Документ базы не существует в OLE-базе: ПриходнаяНакладная №  ПН-000234 от 01.02.2008

Скачать файлы

Наименование Файл Версия Размер
down.zip 41
.zip 10,28Kb
10.02.12
41
.zip 10,28Kb Скачать

См. также

Подписаться Добавить вознаграждение

Комментарии

1. Максим Шуйский (maxpiter) 15.02.12 09:42
Если можно, коротко опишите принцип сравнения табличных частей документов.
Если тестировали, то тысячу документов за какое, приблизительно, время сравнивает?
2. Осипов Сергей (fixin) 15.02.12 10:32
(1) по количеству документов не скажу, но сравнение УТ и Розницы по 40 магазинам за 2,5 года с количеством строк в ОРП где-то 200 в день (+ приходные, списания, перемещения), занимает часов шесть. Учитывая, что документы соотносятся по регистру СоответствияОбъектовОбмена, т.е. для каждого дока идет поиск по GUID (на это тратится некоторое время).

Табличные части сравниваются по сумме. Но если хотите, можете использовать хэш по товарам. Хэш-функций на инфостарте много, хотите, могу свою дать. ;-)
3. Максим Шуйский (maxpiter) 15.02.12 10:42
(2) >> Табличные части сравниваются по сумме
а если номенклатурная позиция изменилась и цена у нее такая же, то сравнение выдаст что документы идентичны?
или же вы хотели сказать, что сравнение идет по контрольной сумме документа?

Спасибо за хеш-функцию, хотите, можете выложить на инфостарт ;-)
4. Осипов Сергей (fixin) 15.02.12 11:06
Ой, простите, не заметил, что это тема про сравнение 7-ки, а не 1с8. Подумал про другую обработку.
ДЛя 1с7 работает быстрее, для ТЧ сопоставляются все реквизиты по UID....

(3) Можете взять за основу эту неуниверсальную функцию, переделав ее на все реквизиты:
Функция ПолучитьСтруктуруДокумента(ДокументОбъект, Проведен = Неопределено) Экспорт
	
	Р = Новый Структура();
	
	МД = ДокументОбъект.Метаданные();
	
	КонтрольнаяСумма = 0;
	
	Если ОбщегоНазначения.ЕстьРеквизитДокумента("Склад", МД) Тогда
		Р.Вставить("Склад", ДокументОбъект.Склад);
	КонецЕсли;
	
	Если ОбщегоНазначения.ЕстьРеквизитДокумента("СкладОтправитель", МД) Тогда
		Р.Вставить("Склад", ДокументОбъект.СкладОтправитель);
	КонецЕсли;
	
	Если ОбщегоНазначения.ЕстьРеквизитДокумента("СкладПолучатель", МД) Тогда
		Р.Вставить("Склад", ДокументОбъект.СкладПолучатель);
	КонецЕсли;
	
	Если ОбщегоНазначения.ЕстьРеквизитДокумента("Контрагент", МД) Тогда
		Р.Вставить("Контрагент", ДокументОбъект.Контрагент);
	КонецЕсли;
	
	Если ОбщегоНазначения.ЕстьРеквизитДокумента("ДоговорКонтрагента", МД) Тогда
		Р.Вставить("ДоговорКонтрагента", ДокументОбъект.ДоговорКонтрагента);
	КонецЕсли;
	
	Если Проведен = Неопределено Тогда
		Р.Вставить("Проведен", ДокументОбъект.Проведен);
	Иначе
		Р.Вставить("Проведен", Проведен);
	КонецЕсли;
	
	Р.Вставить("Дата", НачалоДня(ДокументОбъект.Дата)); //С точностью до начала дня

	
	
	Если Р.Свойство("Склад") Тогда
		КонтрольнаяСумма = КонтрольнаяСумма + УникальныйИдентификаторВЧисло(Р.Склад.УникальныйИдентификатор());
	КонецЕсли;
	Если Р.Свойство("Склад2") Тогда
		КонтрольнаяСумма = КонтрольнаяСумма + УникальныйИдентификаторВЧисло(Р.Склад2.УникальныйИдентификатор());
	КонецЕсли;
	Если Р.Свойство("Контрагент") Тогда
		КонтрольнаяСумма = КонтрольнаяСумма + УникальныйИдентификаторВЧисло(Р.Контрагент.УникальныйИдентификатор());
	КонецЕсли;
	Если Р.Свойство("ДоговорКонтрагента") Тогда
		КонтрольнаяСумма = КонтрольнаяСумма + УникальныйИдентификаторВЧисло(Р.ДоговорКонтрагента.УникальныйИдентификатор());
	КонецЕсли;
	
	Если Р.Проведен Тогда
		КонтрольнаяСумма = КонтрольнаяСумма + 1231231231231878791378192379;
	Иначе
		КонтрольнаяСумма = КонтрольнаяСумма + 8798794323847324923423847234;
	КонецЕсли;
	
	КонтрольнаяСумма = КонтрольнаяСумма + 3412* Год(Р.Дата) + 34879 * Месяц(Р.Дата) + 34349 * День(Р.Дата);

	
	ИтогоКоличество = 0;
	ИтогоСумма = 0;
	
	Если ОбщегоНазначения.ЕстьТабЧастьДокумента("Товары", МД) Тогда
		Для Каждого Строка ИЗ ДокументОбъект.Товары Цикл
			ТекКоличество = 0;
			ТекСумма = 0;
			ТекМножитель = 0;
			Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("Количество", МД, "Товары") Тогда
				ТекКоличество = Строка.Количество;
				Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("Коэффициент", МД, "Товары") И Строка.Коэффициент <> 0 Тогда
					ТекКоличество = ТекКоличество * Строка.Коэффициент;
				КонецЕсли;
			КонецЕсли;
			Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("Сумма", МД, "Товары") Тогда
				ТекСумма = Строка.Сумма;
			КонецЕсли;
			ИтогоКоличество = 	ИтогоКоличество = + ТекКоличество;
			ИтогоСумма = 	ИтогоСумма = + ТекСумма;
			
			Если ОбщегоНазначения.ЕстьРеквизитТабЧастиДокумента("Номенклатура", МД, "Товары")  Тогда
				ТекМножитель = ТекМножитель + УникальныйИдентификаторВЧисло(Строка.Номенклатура.УникальныйИдентификатор());
			КонецЕсли;
			
			ТекМножитель = ТекМножитель + ТекКоличество * 1000000 + ТекСумма;
			
			КонтрольнаяСумма = КонтрольнаяСумма + Строка.НомерСтроки * ТекМножитель;;
			
		КонецЦикла;
	КонецЕсли;
	
	
	//Преобразовываем контрольную сумму в 32 разряда
	КонтрольнаяСумма32 = ВыровнятьКонтрольнуюСумму32(КонтрольнаяСумма); 
	
	Р.Вставить("Количество", ИтогоКоличество);
	Р.Вставить("Сумма", ИтогоСумма);
	Р.Вставить("КонтрольнаяСумма", КонтрольнаяСумма32);
	Р.Вставить("ИсходнаяКонтрольнаяСумма", КонтрольнаяСумма);
	
	Возврат Р;

КонецФункции



//=== МАТЕМАТИКА ПОДПИСЕЙ ===

Функция ВыровнятьКонтрольнуюСумму32(Ч, Делитель = 100000000000000000000000000000000) Экспорт
	ТекЧ = Ч;
	Пока истина Цикл
		Целая = Цел(ТекЧ / Делитель);
		Если Целая < 1 Тогда
			Прервать;
		КонецЕсли;
		ТекЧ = Целая + ТекЧ % Делитель;
	КонецЦикла;
	Возврат ТекЧ;
КонецФункции

Функция УникальныйИдентификаторВЧисло(GUID) Экспорт
    //Назначение: Преобразует GUID в число
 
    //ДатаСоздания: 20080101
 
    //Автор: Fixin
 
    //Тестирована: Да
 
    //Благодарность: Алмазов Петр 
 
    //Ссылка: v8: Как перевести ГУИД в число и обратно?
 
    //Ссылка: http://partners.v8.1c.ru/forum/thread.jsp?id=640731
 
    //Пример: 
 
    //    declare @a uniqueidentifier 
 
    //    set @a = '40bf67bb-742c-4355-abb9-dff6a60bd701' 
 
    //    print cast(@a as varbinary) 
 
    //    0xBB67 BF40 2C74 5543 ABB9 DFF6 A60B D701
 
    //Пример:
 
    //    40bf67bb-742c-4355-abb9-dff6a60bd701'.ToByteArray()=
 
    //    0xBB67 BF40 2C74 5543 ABB9 DFF6 A60B D701
 
    //    '22345200-abe8-4f60-90c8-0d43c5f6c0f6'.ToByteArray()=
 
    //    0x0052 3422 E8AB 604F 90C8 0D43 C5F6 C0F6
 
    //Описание:
 
    //    Конвертирует GUID в число с правильным расположением тетрад.
 
    //    Можно быть уверенным что функции cast языка SQL и ToByteArray языка JAVA конвертируют так же.
 
    
    СтрокаGUID = СтрЗаменить(Строка(GUID),"-","");
    
    //Первая восьмерка
 
    ч1 = Сред(СтрокаGUID, 1, 2);
    ч2 = Сред(СтрокаGUID, 3, 2);
    ч3 = Сред(СтрокаGUID, 5, 2);
    ч4 = Сред(СтрокаGUID, 7, 2);
    
    //Первая четверка
 
    ч5 = Сред(СтрокаGUID, 9, 2);
    ч6 = Сред(СтрокаGUID, 11, 2);
    
    //Вторая четверка
 
    ч7 = Сред(СтрокаGUID, 13, 2);
    ч8 = Сред(СтрокаGUID, 15, 2);
    
    //Хвост
 
    ч9 = Сред(СтрокаGUID, 17, 16);
    
    СтрGUID = ч4 + ч3 + ч2 + ч1 + ч6 + ч5 + ч8 + ч7 + ч9;
    Ч = бфМат.ПереводИзСистемыСчисленияВЧисло(СтрGUID, 16);
    
    Возврат Ч;
КонецФункции

...Показать Скрыть
5. Максим Шуйский (maxpiter) 15.02.12 11:11
(4) это же не 7.7 :)

спасибо за ответы.
6. Осипов Сергей (fixin) 15.02.12 16:35
(5) да, вот я и говорю, что перепутал... строки сравниваюстя по каждому реквизиту 1:1
Для написания сообщения необходимо авторизоваться
Прикрепить файл
Дополнительные параметры ответа