【发布时间】:2017-10-28 14:37:02
【问题描述】:
我目前在下面的代码可以快速有效地在“A”列中查找重复项。我正在处理一个非常大的数据集 40-50,000 行有时更多。虽然这段代码很好,但如果没有找到重复项,它会抛出错误代码。
我可以通过删除“On error go to 0”行来规避这个问题,但它会复制粘贴整个数据集。如果没有找到重复项,有没有办法修改此代码以显示消息框?
如果不是,如果找到重复项并且如果不显示消息框,则可能会有一个单独的 Sub 调用此 Sub?尽管对于大型数据集,许多效率不够。
Sub filtersort()
Dim wsData As Worksheet, wsOutput As Worksheet
Dim Rng As Range
Dim LastRow As Long, LastCol As Long, i As Long, j As Long, n As Long
Dim arr(), x, dict, arrOut()
With Application
.Calculation = xlCalculationManual
.EnableEvents = False
.ScreenUpdating = False
End With
Set wsData = Worksheets("Sheet1")
On Error Resume Next
Set wsOutput = Sheets("Duplicate Data")
wsOutput.Cells.Clear
On Error GoTo 0
If wsOutput Is Nothing Then
Sheets.Add(after:=wsData).Name = "Duplicate Data"
Set wsOutput = ActiveSheet
End If
LastRow = wsData.Range("A" & Rows.Count).End(xlUp).Row
LastCol = wsData.Cells(3, Columns.Count).End(xlToLeft).Column + 1
Set Rng = wsData.Range("A3:A" & LastRow)
x = wsData.Range("A4:V" & LastRow).Value
Set dict = CreateObject("Scripting.Dictionary")
For i = 1 To UBound(x, 1)
If Not dict.exists(x(i, 1)) Then
dict.Item(x(i, 1)) = ""
Else
j = j + 1
ReDim Preserve arr(1 To j)
arr(j) = x(i, 1)
End If
Next i
ReDim arrOut(1 To UBound(x, 1), 1 To UBound(x, 2))
For i = 1 To UBound(x, 1)
If Not IsError(Application.Match(x(i, 1), arr, 0)) Then
n = n + 1
For j = 1 To UBound(x, 2)
arrOut(n, j) = x(i, j)
Next j
End If
Next i
wsData.Range("A3:V3").Copy wsOutput.Range("A3")
wsOutput.Range("A4").Resize(n, UBound(x, 2)).Value = arrOut
LastRow = wsOutput.Cells(Rows.Count, 1).End(xlUp).Row
wsOutput.Range("A3:V" & LastRow).Sort Key1:=wsOutput.Range("A4"),
Order1:=xlDescending, Header:=xlYes
With Application
.Calculation = xlCalculationAutomatic
.EnableEvents = True
.ScreenUpdating = True
End With
End Sub
【问题讨论】:
-
我想到了两个解决方案。 (1)
dict.Count应该为您提供添加到字典中的项目数,可能为零,或者,如果无法完成,则在为零时抛出错误。 (2) 创建一个名为FoundDuplicate的 Boolean 变量,并在字典中添加重复项时将该变量设置为 True。 -
@Variatus 第二种方法更安全、更直接。
-
这段代码是你自己写的吗?我只是好奇你为什么要做
Dictionary.Exists检查,然后是Application.Match检查。这不是检查重复两次吗?您可能会获得一些效率提升。 -
我没有太多使用布尔方法。我会按照“如果 dict.count.value > 1 然后“应用我的代码”如果消息框则结束”的方式做一些事情吗? @Ambie 不,我得到了一些帮助。任何提高效率的建议都会很棒。
-
不,只是
If dict.Count > 0表示字典中有值。 Boolean 是一种数据类型,例如 String 或 Integer,但它只知道 True 和 False。因此,您在发现重复项时设置FoundDuplicate = True,然后再询问If FoundDuplicate = True Then,否则什么也不做。
标签: vba excel duplicates large-data