Вот другой подход, использующий объект Collection VBA, чтобы определить, есть ли совпадение. Он должен выполняться гораздо быстрее, чем методы, которые непосредственно манипулируют листом, но если ваша база данных обширна и выполнение все еще слишком медленное, есть некоторые способы ускорить это.
Источник (исходные данные) и результаты находятся в разных местах на одном листе, но в коде должно быть очевидно, как изменить это (или даже изменить его, чтобы перезаписать исходные данные, если вы этого хотите.
Пробелы не включены Если вы хотите включить, изменения в коде будет тривиальным
Option Explicit
Sub DeleteDuplicateColumnPairs()
Dim wsSrc As Worksheet, wsRes As Worksheet, rRes As Range
Dim vSrc As Variant, vRes() As Variant
Dim colFirst As Collection, colSecond As Collection
Dim I As Long, J As Long, V As Variant
Dim LastRow As Long
'Set Source and Results worksheets and result range
Set wsSrc = Worksheets("sheet3")
Set wsRes = Worksheets("sheet3")
Set rRes = wsRes.Range("D1")
'Get source data
With wsSrc
LastRow = .Range("a1", .Cells(.Rows.Count, "B")).Find(what:="*", after:=[A1], LookIn:=xlValues, _
searchorder:=xlByRows, searchdirection:=xlPrevious).Row
vSrc = .Range("a1", .Cells(LastRow, "B"))
End With
'Collect first column data
'skip header row
Set colFirst = New Collection
On Error Resume Next
For I = 2 To UBound(vSrc, 1)
If Len(vSrc(I, 1)) > 0 Then
colFirst.Add Item:=vSrc(I, 1), Key:=CStr(vSrc(I, 1))
Select Case Err.Number
Case 457
colFirst.Add Item:=vSrc(I, 1)
Err.Clear
Case Is <> 0
Debug.Print Err.Number, Err.Description, Err.Source
Stop 'for debugging.
End Select
End If
Next I
On Error GoTo 0
'collect second column data
'if present in first column, then remove from both
' but will then need to see if there is a duplicate in first column
' and re-enter it with the key
Set colSecond = New Collection
On Error Resume Next
For I = 2 To UBound(vSrc)
If Len(vSrc(I, 2)) > 0 Then
V = colFirst(CStr(vSrc(I, 2)))
Select Case Err.Number
Case 5
colSecond.Add vSrc(I, 2)
Err.Clear
Case 0
colFirst.Remove (CStr(vSrc(I, 2)))
'is there another dup in colFirst?
For J = 1 To colFirst.Count
If colFirst(J) = vSrc(I, 2) Then
colFirst.Remove J
colFirst.Add vSrc(I, 2), CStr(vSrc(I, 2))
Exit For
End If
Next J
Case Else
Debug.Print Err.Number, Err.Description, Err.Source
Stop
End Select
End If
Next I
On Error GoTo 0
'Construct Results Array
ReDim vRes(0 To IIf(colFirst.Count > colSecond.Count, colFirst.Count, colSecond.Count), 1 To 2)
'Populate headers
vRes(0, 1) = vSrc(1, 1)
vRes(0, 2) = vSrc(1, 2)
'Populate the data
For I = 1 To colFirst.Count
vRes(I, 1) = colFirst(I)
Next I
For I = 1 To colSecond.Count
vRes(I, 2) = colSecond(I)
Next I
'Write data to worksheet
Set rRes = rRes.Resize(UBound(vRes, 1) + 1, UBound(vRes, 2))
With rRes
.EntireColumn.Clear
.Value = vRes
.HorizontalAlignment = xlRight
With .Rows(1)
.Font.Bold = True
.HorizontalAlignment = xlCenter
End With
.EntireColumn.AutoFit
End With
End Sub
Вот пример того, что это дает:.
Интересный вопрос! Вы хотите fomular или vba? – HelloNewWorld
Предпочтительно VBA. Это часть более крупной процедуры, но эта часть меня просто застопорилась. – Shannylno5
У меня есть функциональное решение ... Позвольте мне подумать о решении vba ... – HelloNewWorld