Alan Turing
Alan Turing

Reputation: 12571

Merge Data in Excel Range, Removing Blanks and Duplicates

I have a range of cells in Excel that is more than one column wide and more than one row long. Some of the cells are blank. I would like to merge (using VBA) the non-blank cells into a list, remove the duplicates, and sort alphabetically.

For example, given this input (where a dash designates an empty cell for the purpose of this question):

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

The following sorted output is produced:

A
B
C
D
E

As the example input shows, some of the rows and columns in the range may contain all empty cells.

Upvotes: 0

Views: 3808

Answers (1)

Siddharth Rout
Siddharth Rout

Reputation: 149287

Here is one way to do it.

CODE

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

SNAPSHOTS

enter image description here

FOLLOWUP

I just realized that adding 3 lines more makes this code even faster than the above code.

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

Upvotes: 5

Related Questions