Excel 在电子表格中查找并仅保留重复项

Excel 在电子表格中查找并仅保留重复项,excel,vba,Excel,Vba,在Excel中,我创建了一个宏,用于在当前选择的多个列中查找并只保留重复的值——删除所有只找到一次的单元格。好吧,至少我认为我创造了这个,但它似乎不起作用。以下是我得到的: Sub FindDupsRemoveUniq() Dim c As Range Dim counted() As String For Each c In selection.Cells Dim already_found As Boolean already_foun

在Excel中,我创建了一个宏,用于在当前选择的多个列中查找并只保留重复的值——删除所有只找到一次的单元格。好吧,至少我认为我创造了这个,但它似乎不起作用。以下是我得到的:

Sub FindDupsRemoveUniq()
    Dim c As Range
    Dim counted() As String
    For Each c In selection.Cells
        Dim already_found As Boolean
        already_found = Contains(counted, c.Text)
        If Not (already_found) And WorksheetFunction.CountIf(selection, c) <= 1 Then
            c.Delete Shift:=xlUp
        ElseIf ("" <> c.Text) And Not (already_found) Then
            If Len(Join(counted)) = 0 Then
                ReDim counted(1)
            Else
                ReDim Preserve counted(UBound(counted) + 1)
            End If
            counted(UBound(counted) - 1) = c.Text
        End If
    Next c
End Sub

Private Function Contains(ByRef arr() As String, cell As String) As Boolean
    Dim i As Integer
    Contains = False
    If Len(Join(arr)) = 0 Then
        Exit Function
    End If
    For i = LBound(arr) To UBound(arr)
        If cell = arr(i) Then
            Contains = True
            Exit Function
        End If
    Next
End Function
Sub FindDupsRemoveUniq()
调光范围
Dim counted()作为字符串
对于选择单元格中的每个c
已将Dim作为布尔值找到
已找到=包含(已计数,c.Text)

如果没有(已找到)和WorksheetFunction.CountIf(selection,c)如果要从选择中删除所有具有唯一值的单元格,请尝试以下操作:

Sub test()
    Dim rngToDelete As Range, c As Range

    For Each c In Selection
        If WorksheetFunction.CountIf(Selection, c) = 1 Then
            If rngToDelete Is Nothing Then
                Set rngToDelete = c
            Else
                Set rngToDelete = Union(rngToDelete, c)
            End If
        End If
    Next

    If Not rngToDelete Is Nothing Then rngToDelete.Delete Shift:=xlUp
End Sub

我建议使用数组,方法与
simoco

这种方法会删除单元格内容,但不会向上移动单元格,因为我不清楚您是否需要这样做

Sub Kill_Unique()
Dim X
Dim lngRow As Long
Dim lngCol As Long
X = Selection.Value2
For lngRow = 1 To UBound(X, 1)
    For lngCol = 1 To UBound(X, 2)
        If Application.CountIf(Selection, X(lngRow, lngCol)) < 2 Then X(lngRow, lngCol) = vbNullString
    Next lngCol
Next lngRow
Selection.Value2 = X
End Sub
Sub Kill_Unique()
暗X
长得一样长
变暗lngCol为长
X=选择值。值2
对于lngRow=1到UBound(X,1)
对于lngCol=1至UBound(X,2)
如果Application.CountIf(Selection,X(lngRow,lngCol))<2,那么X(lngRow,lngCol)=vbNullString
下一个lngCol
下一个成长
Selection.Value2=X
端接头

对于180k个项目,您的解决方案应该更快:)顺便说一句,我使用了
c.Delete Shift:=xlUp
,因为OP在他们的代码中使用了它。我明天就能知道这是否有效,但我确实喜欢这个。但是有一件事让我很困惑(通常是VB),应该
lngRow
lngCol
0
开始吗?@supercheetah从一个范围构建的变体数组总是从1,1开始),而标准VBA/VB数组的下限可以是0或1,这取决于它的初始化方式(默认值为0)。谢谢@brettdj。这至少让事情变得明朗了一点。当VB中的某些东西从1开始而不是从0开始时,我仍然感到困惑。哦,是的,@simoco是对的。我确实想删除那些单元格,但这应该很容易修改。
Sub Kill_Unique()
Dim X
Dim lngRow As Long
Dim lngCol As Long
X = Selection.Value2
For lngRow = 1 To UBound(X, 1)
    For lngCol = 1 To UBound(X, 2)
        If Application.CountIf(Selection, X(lngRow, lngCol)) < 2 Then X(lngRow, lngCol) = vbNullString
    Next lngCol
Next lngRow
Selection.Value2 = X
End Sub