Option Explicit
Sub Main()
Dim Folder(0 To 1) As String
Dim Files(0 To 1) As Object 'Dictionary
Dim NotFound As Object 'Dictionary
Dim Found As Object 'Dictionary
Dim Item, Result
Dim i As Long, j As Long
Dim fso As Object 'FileSystemObject
'
'Erase used range
Columns("A:I").ClearContents
'
'Setup path to folder
Folder(0) = "C:\temp\Folder_A"
Folder(1) = "C:\temp\Folder_B"
'
'Get all PRN files
For i = 0 To 1
Set Files(i) = FilesToDict(Folder(i), "*.prn")
Next
'
'Compare found files in the other folder and vice versa
Set Found = CreateObject("Scripting.Dictionary")
For i = 0 To 1
j = (i + 1) Mod 2
Set NotFound = CreateObject("Scripting.Dictionary")
For Each Item In Files(i)
If Not Files(j).Exists(Item) Then
NotFound.Add Item, Item
ElseIf i = 0 Then
Found.Add Item, Item
End If
Next
'
'Output the difference to column A and B
With Range("A1")
.Offset(0, i) = "Not in " & Folder(j)
If NotFound.Count > 0 Then
Item = NotFound.Items
.Offset(1, i).Resize(UBound(Item) + 1, 1) = WorksheetFunction.Transpose(Item)
End If
End With
Next
'
'Start the comparing of equal filenames
With Range("C1")
.Value = "Found in both"
Set fso = CreateObject("Scripting.FileSystemObject")
j = 1
'Retrieve all filenames
Item = Found.Items
For i = 0 To UBound(Item)
'Store the filename
.Offset(j, 0) = Item(i)
'Compare the files in both folders
Result = ComparePRN(fso.BuildPath(Folder(0), Item(i)), fso.BuildPath(Folder(1), Item(i))).Items
'Store the result
.Offset(j, 1).Resize(UBound(Result) + 1, 1) = WorksheetFunction.Transpose(Result)
'Next position
j = j + UBound(Result) + 1
Next
'Split result by ; into columns
On Error Resume Next
.Offset(0, 1).EntireColumn.TextToColumns DataType:=xlDelimited, Semicolon:=True
End With
End Sub
Private Function FilesToDict(Path As String, Mask As String) As Object 'Dictionary
Dim fso As Object 'FileSystemObject
Dim F As Object 'File
Set fso = CreateObject("Scripting.FileSystemObject")
Set FilesToDict = CreateObject("Scripting.Dictionary")
FilesToDict.CompareMode = vbTextCompare
If Not fso.FolderExists(Path) Then Exit Function
For Each F In fso.GetFolder(Path).Files
If F.Name Like Mask Then FilesToDict.Add F.Name, F.Name
Next
End Function
Private Function ComparePRN(FName1 As String, FName2 As String) As Object 'Dictionary
Const Delimiter = ";"
Dim fso As Object 'FileSystemObject
Dim TS As Object 'TextStream
Dim Lines(0 To 1)
Dim Word(0 To 1)
Dim Equal8 As Boolean, Equal4 As Boolean
Dim LineNr As Long
Dim i As Integer
Dim Result As String
Set ComparePRN = CreateObject("Scripting.Dictionary")
'Install errorhandler
On Error GoTo ErrorHandler
'Read in the contents
Set fso = CreateObject("Scripting.FileSystemObject")
Set TS = fso.OpenTextFile(FName1)
Lines(0) = Split(TS.ReadAll, vbCrLf)
TS.Close
Set TS = fso.OpenTextFile(FName2)
Lines(1) = Split(TS.ReadAll, vbCrLf)
TS.Close
'Compare the lines starting by line #9 (Note: Our arrays are zero based, means the first line is line #0!)
For LineNr = 8 To WorksheetFunction.Min(UBound(Lines(0)), UBound(Lines(1)))
'Separate the words from the line
For i = 0 To 1
Word(i) = Split(TrimDouble(Trim$(Lines(i)(LineNr)), Compare:=vbBinaryCompare))
Next
'Compare the words #8 and #4
Equal8 = StrComp(Word(0)(7), Word(1)(7), vbTextCompare) = 0
Equal4 = StrComp(Word(0)(3), Word(1)(3), vbTextCompare) = 0
If Equal8 Then
If Equal4 Then
'A. If word#8 (file in folder_A) = word#8 (file in folder_B) _
an word#4 (file in folder_A) = word#4 (file in folder_B) then
' 1. Write "No difference"
' 2. Continue with the next files to compare
If ComparePRN.Count = 0 Then
'Add this only if no differences are in the whole file
Result = "No difference"
ComparePRN.Add LineNr, Result
End If
Exit Function
Else
'C. If word#4 (file in folder_A) <> word # 4 (file in folder_B) then Output
' Word #3 (file1-folderA )__ Word#8 (file1 folderA)__ Word#4 ( _
file1 folderA ) Word# 8 (file2, Folder B)_ Word#4 ( file 2, _
Folder B)__"length different"
Result = ""
Result = Result & Word(0)(2) & Delimiter
Result = Result & Word(0)(7) & Delimiter
Result = Result & Word(0)(3) & Delimiter
Result = Result & Word(1)(7) & Delimiter
Result = Result & Word(1)(3) & Delimiter
Result = Result & "length different"
ComparePRN.Add LineNr, Result
End If
Else
If Equal4 Then
'B. If word # 8 (file in folder_A) <> word # 8 (file in folder_B) then Output
'(starting at column"A")
' Word #3 (file1-folderA )__ Word#8 (file1 folderA)__ Word#4 ( _
file1 folderA ) Word# 8 (file2, Folder B)_ Word#4 ( file 2, _
Folder B)__"name different"
Result = ""
Result = Result & Word(0)(2) & Delimiter
Result = Result & Word(0)(7) & Delimiter
Result = Result & Word(0)(3) & Delimiter
Result = Result & Word(1)(7) & Delimiter
Result = Result & Word(1)(3) & Delimiter
Result = Result & "name different"
ComparePRN.Add LineNr, Result
Else
'D. If word# 8 <> word # 8 and word# 4 <> word #4 then produce _
the same output line described in item "B" but say"line is " & _
"different"
Result = ""
Result = Result & Word(0)(2) & Delimiter
Result = Result & Word(0)(7) & Delimiter
Result = Result & Word(0)(3) & Delimiter
Result = Result & Word(1)(7) & Delimiter
Result = Result & Word(1)(3) & Delimiter
Result = Result & "line is different"
ComparePRN.Add LineNr, Result
End If
End If
Next
Exit Function
ErrorHandler:
Result = "Error " & Err.Number & " in Line " & LineNr & ": " & Err.Description
ComparePRN.Add LineNr, Result
End Function
Function TrimDouble(ByVal S As String, Optional ByVal Delim As String = " ", _
Optional ByVal ConsecutiveDelim As Boolean = False, _
Optional ByVal Compare As VbCompareMethod = vbTextCompare) As String
'Liefert einen String in dem keine mehrfachen (Leer-)Zeichen mehr sind
Dim i As Long, DoubleDelim As String, SingleDelim As String
If ConsecutiveDelim Or Len(Delim) = 1 Then
DoubleDelim = Delim & Delim
Do While InStr(1, S, DoubleDelim, Compare) > 0
S = Replace$(S, DoubleDelim, Delim, Compare:=Compare)
Loop
Else
For i = 1 To Len(Delim)
SingleDelim = Mid$(Delim, i, 1)
DoubleDelim = String$(2, SingleDelim)
Do While InStr(1, S, DoubleDelim, Compare) > 0
S = Replace$(S, DoubleDelim, SingleDelim, Compare:=Compare)
Loop
Next
End If
TrimDouble = S
End Function
Bookmarks