Страницы: 1
RSS
VBA. Сравнение файлов Excel на идентичность, Сохранение файлов из outlook и проверка хэша
 
Описание: На почту каждый день от исполнителя (таких сотни) приходит файл xls. Каждый день новый. Макрос сохраняет его на диск в нужную папку.
Проблема: Часто приходят файлы не за тот день, старые, идентичные уже сохраненным. (Сравнение по дате создания, имени и другим атрибутам файла не подходит). Пытаюсь сделать проверку по хэш сумме, но аутлук даже один и тот же файл (Файлы сохраняю в одну папку, но с разными именами) сохраняет их с разными байтами, что ведёт к разному хэшу. Пробовал сохранять и через ActiveWorkbook.SaveAs и через objMail.Attachments.SaveAsFile, байты у двух одинаковых файлов выходят разные.
И не могу понять почему так.
Подскажите где просчёт, и подскажите, как тогда их сравнить на идентичность. П.с открытие файлов и сравнение уже содержимого не подразумевается из-за слишком большого количества файлов.

Читаю байты следующей функцией
Скрытый текст

Код полностью пока не вижу смысла выкладывать, т.к. проблема скорее в том, что я что-то не учёл или не знаю:)
Изменено: Sanja - 13.08.2026 12:18:04
 
Здравствуйте.
В самом файле есть какая-нибудь уникальная информация? Например,  номер номер счета или какого-нибудь договора. Это я к тому, что можно сделать лист в книге Excel со списком загруженных счетов или договоров и при загрузке нового файла проверять не был ли загружен документ с такими реквизитами.
 
Добрый день.
Ещё вариант - побайтное сравнение файлов макросом.
Подсказка: в макросе прилагаемого файла есть закомментированная ошибка непонятного происхождения.  
 
Цитата
Никита Дворец написал:
есть закомментированная ошибка непонятного происхождения
Почему не понятная, так массивы не сравнивают.
 
Цитата
так массивы не сравнивают.

Точно! Например так:
Код
Function ByteArraysAreEqual(data1() As Byte, data2() As Byte) As Boolean
    Dim i As Integer
    Dim len As Integer
    len = UBound(data1) ' Предполагаем, что оба массива имеют одинаковую верхнюю границу
    
    ' Сначала проверяем длину — это быстрая отсечка
    If len <> UBound(data2) Then
        ByteArraysAreEqual = False
        Exit Function
Else
' Поэлементное сравнение
For i = LBound(data1) To len
If data1(i) <> data2(i) Then
ByteArraysAreEqual = False
Exit Function
End If
Next i
 End If

    ' Если все элементы совпали
    ByteArraysAreEqual = True
End Function
 
Aлeкceй, к сожалению нет, ничего такого, на что можно положиться
Никита Дворец, Сравнение файлов - это я уже реализовал, через создание и сравнение хэшей, но это на следующем этапе и там всё ок. Проблемка то заключается в том, что байты не совпадают у одинаковых файлов. И проблема где-то в сохранении.  
 
Цитата
ger-a-sim написал:
Пробовал сохранять и через ActiveWorkbook.SaveAs
При таком сохранении в файле каждый раз сохраняется новое значение даты-времени изменения (сохранения).
Соответственно, каждый сохраненный в другое время файл будет отличаться от своей копии.

Цитата
и через objMail.Attachments.SaveAsFile, байты у двух одинаковых файлов выходят разные
Что-то не так делаете. Перешлите себе один и тот же файл 2 раза и сохраните вложение, не открывая книгу в Excel, через .SaveAsFile с разными именами - бинарный состав будет одинаков. Учтите только пункт выше.
Изменено: ZVI - 14.08.2026 05:38:41
 
Думается, надо учитывать для сравнения только определённую часть файла, которую не затрагивает временная метка, но это, как идея..
 
Цитата
testuser написал:
учитывать для сравнения только определённую часть файла
Парсить бинарный XLS - то еще удовольствие  ;)
 
Цитата
ZVI написал:
Что-то не так делаете. Перешлите себе один и тот же файл 2 раза и сохраните вложение, не открывая книгу в Excel, через .SaveAsFile с разными именами - бинарный состав будет одинаков. Учтите только пункт выше.
Кстати, не обратил, внимани, действительно, что-то не так, сторонняя прога, не должна менять бинарный состав иначе не порядок..
Изменено: testuser - 14.08.2026 12:15:41
 
ZVI, да, у меня сохраняется файл через objMail.Attachments.SaveAsFile, но сначала открывается и проверяется наличие некоторых маркеров (стандартизированные названия в определенных ячейках).
Подскажите, а если через ExecuteExcel4Macro обратиться к маркерам, байты поменяются?
Потестировать сейчас нет времени, потому спрашиваю.
Или может другую схему какую посоветуете, как проверить маркер внутри файла так, чтобы не поменялись байты файла..
Изменено: ger-a-sim - 18.08.2026 11:53:10
 
Так открытие же по условиям задачи "не подразумевается"...
 
Цитата
написал:
Так открытие же по условиям задачи "не подразумевается"...
Ну немного не так выразился - "открытие с последующим сравнением содержимого файлов для выявления идентичности не подразумевается"
А на ExecuteExcel4Macro я только недавно наткнулся, чтобы обращаться к содержимому без открытия файла, и ещё его не интегрировал и не проверял на скорость,
Изменено: ger-a-sim - 18.08.2026 11:52:12
 
Цитата
ger-a-sim написал:
сохраняется файл через objMail.Attachments.SaveAsFile, но сначала открывается и проверяется наличие некоторых маркеров
Очевидно, не сначала, а после .SaveAsFile
Открывать можно только для чтения:
Workbooks.Open "D:\Test1.xlsx", ReadOnly:=True
Или открыть, проверить и закрыть без сохранения
Изменено: ZVI - 18.08.2026 21:14:43
 
Цитата
написал:
Или может другую схему какую посоветуете, как проверить маркер внутри файла так, чтобы не поменялись байты файла
Думаю, что можно проверять маркер в отдельной короткоживущей копии файла...
 
Спасибо всем, причины понял, как реализовать понял.  
Страницы: 1
Читают тему
Наверх