Sub test()
Dim dic1 As Object, dic2 As Object, e, x
Dim MatchA(), MatchB(), MatchAWithin(), MatchBwithin(), NoMatchWithA(), NoMatchWithB()
Dim ma As Long, mb As Long, maw As Long, mbw As Long, nma As Long, nmb As Long
Dim rng1 As Range, rng2 As Range
Dim a, i As Long, ii As Long, txt As String, ubMax As Long, ub As Integer
On Error Resume Next
Set rng1 = Application.InputBox("Select 1st Data Area", Type:=8)
Col1 = Application.InputBox("Enter n th col ref from the left for 1st data", Type:=1)
Set rng2 = Application.InputBox("Select 2nd Data Area", Type:=8)
Col2 = Application.InputBox("Enter n th col ref from the left for 2nd data", Type:=1)
On Error GoTo 0
If (rng1 Is Nothing) + (rng2 Is Nothing) Then Exit Sub
Set dic1 = CreateObject("scripting.dictionary")
dic1.comparemode = vbTextCompare
Set dic2 = CreateObject("scripting.dictionary")
dic2.comparemode = vbTextCompare
a = rng1.Value: ubMax = UBound(a, 1): ub = UBound(a, 2)
ReDim MatchAWithin(1 To ubMax, 1 To ub)
maw = 1: MatchAWithin(1, 1) = "Duplicates within Data1"
For i = 1 To UBound(a, 1)
For ii = 1 To ub
txt = txt & ";;" & a(i, ii)
Next
If Not dic1.exists(a(i, Col1)) Then
dic1.Add a(i, Col1), txt
Else
maw = maw + 1
For ii = 1 To ub: MatchAWithin(maw, ii) = a(i, ii): Next
End If
txt = ""
Next
a = rng2.Value: ubMax = WorksheetFunction.Max(ubMax, UBound(a, 1))
ReDim MatchBwithin(1 To UBound(a, 1), 1 To ub)
mbw = 1: MatchBwithin(1, 1) = "Duplicates within Data2"
For i = 1 To UBound(a, 1)
For ii = 1 To UBound(a, 2)
txt = txt & ";;" & a(i, ii)
Next
If Not dic2.exists(a(i, Col2)) Then
dic2.Add a(i, Col2), txt
Else
mbw = mbw + 1
For ii = 1 To UBound(a, 2): MatchBwithin(mbw, ii) = a(i, ii): Next
End If
txt = ""
Next
ReDim NoMatchWithA(1 To ubMax, 1 To ub)
nma = 1: NoMatchWithA(1, 1) = "No match with Data1"
ReDim MatchA(1 To ubMax, 1 To ub)
ma = 1: MatchA(1, 1) = "Match with Data2"
For Each e In dic2.keys
x = Split(Mid$(dic2(e), 3), ";;")
If dic1.exists(e) Then
ma = ma + 1
For i = 0 To UBound(x): MatchA(ma, i + 1) = x(i): Next
Else
nma = nma + 1
For i = 0 To UBound(x): NoMatchWithA(nma, i + 1) = x(i): Next
End If
Next
ReDim NoMatchWithB(1 To ubMax, 1 To ub)
nmb = 1: NoMatchWithB(1, 1) = "No match with Data2"
ReDim MatchB(1 To ubMax, 1 To ub)
mb = 1: MatchB(1, 1) = "Match with Data1"
For Each e In dic1.keys
x = Split(Mid$(dic1(e), 3), ";;")
If dic2.exists(e) Then
mb = mb + 1
For i = 0 To UBound(x): MatchB(mb, i + 1) = x(i): Next
Else
nmb = nmb + 1
For i = 0 To UBound(x): NoMatchWithB(nmb, i + 1) = x(i): Next
End If
Next
With Range("j1")
.Resize(, ub * 2 + 1).EntireColumn.Clear
With .Resize(ma, ub)
.Value = MatchA
.Borders.Weight = xlHairline
.BorderAround Weight:=xlThin
End With
With .Offset(ma + 1).Resize(maw, ub)
.Value = MatchAWithin
.Borders.Weight = xlHairline
.BorderAround Weight:=xlThin
End With
With .Offset(ma + maw + 2).Resize(nmb, ub)
.Value = NoMatchWithB
.Borders.Weight = xlHairline
.BorderAround Weight:=xlThin
End With
With .Offset(, ub + 1)
With .Resize(mb, ub)
.Value = MatchB
.Borders.Weight = xlHairline
.BorderAround Weight:=xlThin
End With
With .Offset(mb + 1).Resize(mbw, ub)
.Value = MatchBwithin
.Borders.Weight = xlHairline
.BorderAround Weight:=xlThin
End With
With .Offset(mb + mbw + 2).Resize(nma, ub)
.Value = NoMatchWithA
.Borders.Weight = xlHairline
.BorderAround Weight:=xlThin
End With
End With
End With
End Sub