1

I want to sort my rows based on the values in column G. There are 3 possible values: Green, Red and Yellow. I want the rows sorted with Green on top, then Yellow, then Red.

Everything I try results in the sort order being alphabetical: Green, Red then Yellow. There is a secondary sort on column R, but that is working fine.

My latest code is below. rr is the number of the last row. I have tried it with and without Order1:=xlAscending.

sCustomList = "Green" "Yellow" "Red"

Application.AddCustomList ListArray:=sCustomList
    Range("A3:T" & rr).Sort Key1:=Range("G3:G" & rr), Order1:=xlAscending, _
    OrderCustom:=Application.CustomListCount + 1, MatchCase:=False, _
    DataOption1:=xlSortNormal, Key2:=Range("R3:R" & rr), Order2:=xlAscending
2
  • 1
    see Sort data using a custom list. Commented Sep 20, 2015 at 16:59
  • Thanks Jeeped. I see how that works, but I need to be able to do it using VBA. This is part of a much larger macro Commented Sep 20, 2015 at 17:15

3 Answers 3

2

Looking at your code, the sCustomList looks like a string type variable and not a variant array. My success with custom sort lists has been to create a new one every time and use the highest index number to reference it.

Sub custom_sort()
    Dim vCustom_Sort As Variant, rr As Long

    vCustom_Sort = Array("green", "yellow", "red", Chr(42))
    Application.AddCustomList ListArray:=vCustom_Sort

    With Worksheets("Sheet2")    '<~~ set this properly!
        .Sort.SortFields.Clear
        rr = .Cells(Rows.Count, "G").End(xlUp).Row
        With .Range("A3:T" & rr)
            'use this to presort one or more secondary fields before the primary custom sort
            '.Cells.Sort Key1:=.Columns(18), Order1:=xlAscending, _
                        Key2:=.Columns(1), Order2:=xlDescending, _
                        Orientation:=xlTopToBottom, Header:=xlYes
            .Cells.Sort Key1:=.Columns(7), Order1:=xlAscending, _
                        Orientation:=xlTopToBottom, Header:=xlYes, MatchCase:=False, _
                        OrderCustom:=Application.CustomListCount + 1

        End With
        .Sort.SortFields.Clear
    End With

End Sub

There is a twist between .Cells.Sort.SortFields.Add and .Cells.Sort that usually generates some confusion. The .SortFields.Add method uses a CustomOrder:= parameter and the Range.Sort method uses a OrderCustom:= parameter. The two are most definitely NOT the same but often get used interchangeably with disastrous results.

Sign up to request clarification or add additional context in comments.

1 Comment

For the custom lists, I've used the GetCustomListNum method to see if the list exists. The method returns 0 if it does not.
2

If you use the SortFields object, you don't have to refer to custom lists: It should be obvious below where to change the various range references. I also added an alphabetical sort on one of the columns other than G


Option Explicit
Sub TrafficLightSort()
    Dim WS As Worksheet
    Dim rSortRange As Range, rSortKey As Range
    Const sSortOrder As String = "Green,Yellow,Red"

Set WS = Worksheets("sheet1")
With WS
    Set rSortRange = Range("E1", .Cells(.Rows.Count, "E").End(xlUp)).Resize(columnsize:=3)
    Set rSortKey = rSortRange.Columns(3)

    With .Sort.SortFields
        .Clear
        .Add Key:=rSortKey, _
            SortOn:=xlSortOnValues, _
            Order:=xlAscending, _
            CustomOrder:=sSortOrder
        .Add Key:=rSortRange.Columns(1), _
            SortOn:=xlSortOnValues, _
            Order:=xlAscending
    End With

    With .Sort
        .SetRange rSortRange
        .Header = xlNo
        .MatchCase = False
        .Orientation = xlTopToBottom
        .Apply
    End With
End With

End Sub

Comments

0

I would recommend adding a table with an explicit sorting order to your worksheet (green = 1, yellow = 2, etc). Then add a column to your sorting range that uses a lookup function to return the sorting value and use VBA to run a standard sort based on that column. This will leave you with VBA code that is easier for developers to read, allows Excel users who don't read VBA to see your sort order, and avoids burying hardcoded values deep in you macro.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.