【问题标题】:Merge Data in Excel Range, Removing Blanks and Duplicates合并 Excel 范围内的数据,删除空白和重复项
【发布时间】:2012-03-28 05:04:13
【问题描述】:

我在 Excel 中有一个多于一列宽且多于一行长的单元格区域。有些单元格是空白的。我想将非空白单元格合并(使用 VBA)到一个列表中,删除重复项,然后按字母顺序排序。

例如,给定此输入(其中破折号表示此问题的空单元格):

-  -  A  D  -
C  -  -  A  -
-  -  B  -  D
-  -  -  -  -
A  -  -  E  -

产生以下排序输出:

A
B
C
D
E

如示例输入所示,该范围内的某些行和列可能包含所有空单元格。

【问题讨论】:

标签: vba sorting excel duplicates


【解决方案1】:

这是一种方法。

代码

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim LastRow As Long, lastCol As Long, i as Long
    Dim Rng As Range, aCell As Range
    Dim MyCol As New Collection
    
    '~~> Change this to the relevant sheet name
    Set ws = Sheets("Sheet21")
    
    With ws
        LastRow = .Cells.Find(What:="*", After:=.Range("A1"), _
        Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
        SearchDirection:=xlPrevious, MatchCase:=False).Row
        
        lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _
        Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
        SearchDirection:=xlPrevious, MatchCase:=False).Column
        
        Set Rng = .Range("A1:" & Split(.Cells(, lastCol).Address, "$")(1) & LastRow)
        
        'Debug.Print Rng.Address
        For Each aCell In Rng
            If Not Len(Trim(aCell.Value)) = 0 Then
                On Error Resume Next
                MyCol.Add aCell.Value, """" & aCell.Value & """"
                On Error GoTo 0
            End If
        Next
        
        .Cells.ClearContents
        
        For i = 1 To MyCol.Count
            .Range("A" & i).Value = MyCol.Item(i)
        Next i
        
        '~~> OPTIONAL (In Case you want to sort the data)
        .Columns(1).Sort Key1:=.Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
        DataOption1:=xlSortNormal
    End With
End Sub

快照

跟进

我刚刚意识到,多加 3 行代码会使这段代码比上面的代码更快。

Option Explicit

Sub Sample()
    Dim ws As Worksheet
    Dim LastRow As Long, lastCol As Long, i As Long
    Dim Rng As Range, aCell As Range, delRange As Range '<~~ Added This
    Dim MyCol As New Collection

    '~~> Change this to the relevant sheet name
    Set ws = Sheets("Sheet1")

    With ws
        '~~> Get all the blank cells
        Set delRange = .Cells.SpecialCells(xlCellTypeBlanks)  '<~~ Added This
        
        '~~> Delete the blank cells
        If Not delRange Is Nothing Then delRange.Delete  '<~~ Added This
        
        LastRow = .Cells.Find(What:="*", After:=.Range("A1"), _
        Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByRows, _
        SearchDirection:=xlPrevious, MatchCase:=False).Row

        lastCol = .Cells.Find(What:="*", After:=.Range("A1"), _
        Lookat:=xlPart, LookIn:=xlFormulas, SearchOrder:=xlByColumns, _
        SearchDirection:=xlPrevious, MatchCase:=False).Column
        
        Set Rng = .Range("A1:" & Split(.Cells(, lastCol).Address, "$")(1) & LastRow)

        'Debug.Print Rng.Address
        For Each aCell In Rng
            If Not Len(Trim(aCell.Value)) = 0 Then
                On Error Resume Next
                MyCol.Add aCell.Value, """" & aCell.Value & """"
                On Error GoTo 0
            End If
        Next

        .Cells.ClearContents

        For i = 1 To MyCol.Count
            .Range("A" & i).Value = MyCol.Item(i)
        Next i

        '~~> OPTIONAL (In Case you want to sort the data)
        .Columns(1).Sort Key1:=.Range("A1"), Order1:=xlAscending, Header:=xlGuess, _
        OrderCustom:=1, MatchCase:=False, Orientation:=xlTopToBottom, _
        DataOption1:=xlSortNormal
    End With
End Sub

【讨论】:

  • 我会说这就是这样做的方法。 +1 如果需要,您可以在临时工作表上进行排序并重新加载到数组中。
  • +1 很好的解决方案。尽管我总是使用SpecialCells 进行错误测试,以防万一。同样,最好测试单元格存在而不是直接使用FInd 设置行和列
  • 关于specialcells 错误处理的要点。我总是包括它。不知道为什么我在这里错过了:)
猜你喜欢
  • 2017-02-15
  • 2020-03-02
  • 1970-01-01
  • 1970-01-01
  • 2018-08-09
  • 2016-10-24
  • 1970-01-01
  • 2020-01-24
  • 2018-03-11
相关资源
最近更新 更多