清除(而不是删除)重复项并使用VBA保留第一个条目

清除(而不是删除)重复项并使用VBA保留第一个条目,vba,excel,Vba,Excel,我想清除表的第一列中的所有重复值,但保留第一个条目 如果我的表格如以下示例所示: A B C 001 Katy Argentina 002 Katy Argentina Katy Argentina 002 Katy Argentina 004 Katy Argentina 001 Katy

我想清除表的第一列中的所有重复值,但保留第一个条目

如果我的表格如以下示例所示:

    A          B          C
    001        Katy   Argentina
    002        Katy   Argentina
               Katy   Argentina
    002        Katy   Argentina
    004        Katy   Argentina
    001        Katy   Argentina
预期结果:

    A          B          C
    001        Katy   Argentina
    002        Katy   Argentina
               Katy   Argentina
               Katy   Argentina
    004        Katy   Argentina
               Katy   Argentina
我的第一个解决方案是创建一个带有Countif公式的新列,如下所示:

=IF(COUNTIF($A$1:A1,A1)=1,A1,”)

这是非常好的工作,但我的表包含几个列和300000行,所以当我运行这个过程时,大约需要3个小时

是否可以使用VBA运行此功能?

请考虑:

Sub ClearV()
    Dim N As Long
    N = Cells(Rows.Count, "A").End(xlUp).Row
    For i = N To 2 Step -1
        Set rlook = Range(Cells(i - 1, "A"), Cells(1, 1))
        If Application.WorksheetFunction.CountIf(rlook, Cells(i, "A")) > 0 Then
            Cells(i, "A").Clear
        End If
    Next i
End Sub
考虑:

Sub ClearV()
    Dim N As Long
    N = Cells(Rows.Count, "A").End(xlUp).Row
    For i = N To 2 Step -1
        Set rlook = Range(Cells(i - 1, "A"), Cells(1, 1))
        If Application.WorksheetFunction.CountIf(rlook, Cells(i, "A")) > 0 Then
            Cells(i, "A").Clear
        End If
    Next i
End Sub
这相当快:

Sub Tester()
    Dim t
    'create some repeating data
    With Range("A2:A300000")
        .Formula = "=ROUND(RAND()*1000,0)"
        .Value = .Value
    End With

    t = Timer
    ClearDups Range("A2:A300000")  'remove the dups
    Debug.Print Timer - t & " sec"  ' < 1sec
End Sub


Sub ClearDups(rng As Range)
    Dim data, dict As Object, r As Long, nR As Long, tmp
    Set dict = CreateObject("scripting.dictionary")

    Set rng = rng.Columns(1) 'make sure only one column...
    data = rng.Value      'grab data in an array
    nR = UBound(data, 1)
    'loop over the array
    For r = 1 To nR
        tmp = data(r, 1)
        If Len(tmp) > 0 Then
        If dict.exists(tmp) Then
            data(r, 1) = "" 'seen this value before - clear it
        Else
            dict.Add tmp, 1  'first time for this value
        End If
        End If
    Next r
    rng.Value = data 'dump the array back to the range
End Sub
子测试仪()
暗t
'创建一些重复数据
范围(“A2:A300000”)
.Formula=“=ROUND(RAND()*1000,0)”
.Value=.Value
以
t=计时器
ClearDups范围(“A2:A300000”)“删除DUP
调试.打印计时器-t和“秒”<1秒
端接头
子ClearDups(rng As范围)
Dim数据,dict作为对象,r作为长,nR作为长,tmp
Set dict=CreateObject(“scripting.dictionary”)
设置rng=rng.Columns(1)'确保只有一列。。。
data=rng.Value“获取数组中的数据”
nR=UBound(数据,1)
'在阵列上循环
对于r=1至nR
tmp=数据(r,1)
如果Len(tmp)>0,则
如果dict.exists(tmp),则
数据(r,1)=“以前见过此值-清除它”
其他的
添加tmp,该值第一次为1'
如果结束
如果结束
下一个r
rng.Value=数据“将数组转储回范围”
端接头
这非常快:

Sub Tester()
    Dim t
    'create some repeating data
    With Range("A2:A300000")
        .Formula = "=ROUND(RAND()*1000,0)"
        .Value = .Value
    End With

    t = Timer
    ClearDups Range("A2:A300000")  'remove the dups
    Debug.Print Timer - t & " sec"  ' < 1sec
End Sub


Sub ClearDups(rng As Range)
    Dim data, dict As Object, r As Long, nR As Long, tmp
    Set dict = CreateObject("scripting.dictionary")

    Set rng = rng.Columns(1) 'make sure only one column...
    data = rng.Value      'grab data in an array
    nR = UBound(data, 1)
    'loop over the array
    For r = 1 To nR
        tmp = data(r, 1)
        If Len(tmp) > 0 Then
        If dict.exists(tmp) Then
            data(r, 1) = "" 'seen this value before - clear it
        Else
            dict.Add tmp, 1  'first time for this value
        End If
        End If
    Next r
    rng.Value = data 'dump the array back to the range
End Sub
子测试仪()
暗t
'创建一些重复数据
范围(“A2:A300000”)
.Formula=“=ROUND(RAND()*1000,0)”
.Value=.Value
以
t=计时器
ClearDups范围(“A2:A300000”)“删除DUP
调试.打印计时器-t和“秒”<1秒
端接头
子ClearDups(rng As范围)
Dim数据,dict作为对象,r作为长,nR作为长,tmp
Set dict=CreateObject(“scripting.dictionary”)
设置rng=rng.Columns(1)'确保只有一列。。。
data=rng.Value“获取数组中的数据”
nR=UBound(数据,1)
'在阵列上循环
对于r=1至nR
tmp=数据(r,1)
如果Len(tmp)>0,则
如果dict.exists(tmp),则
数据(r,1)=“以前见过此值-清除它”
其他的
添加tmp,该值第一次为1'
如果结束
如果结束
下一个r
rng.Value=数据“将数组转储回范围”
端接头

VBA不会让它更快。你试过在不同的计算机上做同样的事情吗?VBA不会让它更快。你试过在不同的电脑上做同样的事情吗?这真的很有帮助,而且比我想象的要快。非常感谢你!这真的很有帮助而且比我想象的要快。非常感谢你!萨卢多斯。