Is there a faster/better way to accomplish scan of a range for unique text values/save those unique values to range, sort alphabetically?

johnnyL

Well-known Member
Joined
Nov 7, 2011
Messages
4,546
Office Version
  1. 2007
Platform
  1. Windows
Book1.xlsm
ABCDEFGHIJKLMNOPQRSTU
1
2
3Red146Green83Blue13Brown410Black25
4Blue21Purple27Red42Green61
5Green52Orange61Orange47
6Red05Purple83
7Yellow49
8Black1213
Sheet1


Back to this file ...

I want to capture unique text values from a range, sort that range, into the A column, and possibly even count the occurrences of each unique text value found into the corresponding B column.

The following is the code that I have came up with thus far ...

VBA Code:
Sub Find_PrintUniqueNonNumericTextFoundInSelectedRangeToRangeAndSortFoundTextAlphabetically()    ' Works
    Dim DataFoundInCell As Range, r As Range, x0
'
'   \/ Variables to set \/
    SortRange1stCellAddress = "C3"
    SortRangeLastCellAddress = "U8"
'
    With CreateObject("scripting.dictionary")
        For Each DataFoundInCell In ActiveSheet.Range(SortRange1stCellAddress & ":" & SortRangeLastCellAddress).SpecialCells(2)
            If Not IsNumeric(DataFoundInCell) Then x0 = .Item(DataFoundInCell.Value)      '
        Next
'
        Set r = Cells(1, "A").Resize(.Count, 1)                 '
'
        r.Value = Application.Transpose(.Keys)                  '
    End With
'
'   Sort Column A, that now contains the unique text values, alphabetically
'   \/ Variables to set \/
    SortRange1stCellAddress = "A1"
    SheetName = "Sheet1"
'
    SortRangeLastCellAddress = Range(SortRange1stCellAddress).End(xlDown).Address(0, 0)     '
'
    ActiveWorkbook.Worksheets(SheetName).Sort.SortFields.Clear
    ActiveWorkbook.Worksheets(SheetName).Sort.SortFields.Add Key:=Range(SortRange1stCellAddress), Order:=xlAscending    ' Predominant sort starting address
'
    With ActiveWorkbook.Worksheets(SheetName).Sort
        .SetRange Range(SortRange1stCellAddress & ":" & SortRangeLastCellAddress)
        .Header = xlNo
        .Apply
    End With
End Sub
 
How about
VBA Code:
Sub JonnyL()
   Dim Cl As Range
   Dim Tmp As Variant
   
   With CreateObject("scripting.dictionary")
      For Each Cl In Range("D3:V8").SpecialCells(xlConstants, xlTextValues)
         If Not .Exists(Cl.Value) Then
            .Item(Cl.Value) = Array(Cl.Offset(, 1).Value, 1)
         Else
            Tmp = .Item(Cl.Value)
            Tmp(0) = Tmp(0) + Cl.Offset(, 1).Value
            Tmp(1) = Tmp(1) + 1
            .Item(Cl.Value) = Tmp
         End If
      Next Cl
      Range("A2").Resize(.Count, 1).Value = Application.Transpose(.Keys)
      Range("B2").Resize(.Count, 2).Value = Application.Index(.Items, 0)
      Range("A2").Resize(.Count, 3).Sort Range("A1"), xlAscending, , , , , , xlYes
   End With
End Sub

+Fluff 1.xlsm
ABCDEFGHIJKLMNOPQRSTUV
1ColourQty Ordered
2Brown41
3Black142Red146Green83Blue13Brown410Black25
4Blue32Blue21Purple27Red42Green61
5Green193Green52Orange61Orange47
6Orange102Red05Purple83
7Purple102Yellow49
8Red183Black1213
9Yellow41
10
Main
 
Upvote 0

Excel Facts

Excel motto
Not everything I do at work revolves around Excel. Only the fun parts.
Again, Thank you so much @Fluff !!!

I encountered one tiny error in your code.
VBA Code:
Range("A2").Resize(.Count, 3).Sort Range("A1"), xlAscending, , , , , , xlYes

The 'A2' should be 'A1' OR the xlYes should be xlNo. I chose the 'A1' fix.

Now I just have to look at the code and try to digest the ineer workings of it. :) Thanks again!
 
Upvote 0
You're welcome & thanks for the feedback.
 
Upvote 0
How would I do it so the B & C column results were switched? In other words, the current B column results into the C column and the current C column results into the B column.
 
Upvote 0
Just swap the values round in the array & the Tmp array
 
Upvote 0
Just swap the values round in the array & the Tmp array
I already tried:
VBA Code:
            Tmp(0) = Tmp(0) + 1
            Tmp(1) = Tmp(1) + Cl.Offset(, 2).Value

Not sure what else needs to be changed, but that change alone didn't work.
 
Upvote 0
You also need to swap then round on this line
VBA Code:
Array(Cl.Offset(, 1).Value, 1)
 
Upvote 0
I see, said the blind man to his deaf wife as he picked up the hammer and saw.

Thanks again again @Fluff !!!
 
Upvote 0
Another follow up question please.

In the line:

VBA Code:
Array(Cl.Offset(, 1).Value, 1)

Why/How does the '1' at the end of the line equate to the counter? Why doesn't it use the same format as:

VBA Code:
Cl.Offset(, ?).Value

What makes the '1' so magical, and the Cl.Offset method not work for the counter? :)
 
Upvote 0

Forum statistics

Threads
1,214,950
Messages
6,122,428
Members
449,083
Latest member
Ava19

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top