Home » excel » excel – Sorting By Range

excel – Sorting By Range

Posted by: admin May 14, 2020 Leave a comment

Questions:

I have this and it works, but I need it to sort on the specific range. It may not always be 39 rows down.

   ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("L12:L39") _
        , SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
        "AmEx,Discover,Master Card,Visa,Check", DataOption:=xlSortNormal

So I did this, but it still doesn’t work.

ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("L12", Selection.End(xlDown)) _
    , SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
    "AmEx,Discover,Master Card,Visa,Check", DataOption:=xlSortNormal

What am I doing wrong? I think this might be simple but I’m just not seeing it.

This is my full code for that part.

ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("L12", Selection.End(xlDown)) _
    , SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
    "AmEx,Discover,Master Card,Visa,Check", DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("J12", Selection.End(xlDown)) _
    , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal

    With ActiveWorkbook.Worksheets("Sheet1").Sort
    .SetRange Range("B11", Selection.End(xlDown))
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply

It says 1004 the sort reference is not valid.

'*** Sorting by payment method
    Range("L12").Select                                                     '*** Check this sorting for the correct cells
    Range(Selection, Selection.End(xlDown)).Select
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("L12", Selection.End(xlDown)) _
        , SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:= _
        "AmEx,Discover,Master Card,Visa,Check", DataOption:=xlSortNormal
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("J12", Selection.End(xlDown)) _
        , SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal


    Dim sht2 As Worksheet
    Dim LastRow2 As Long
    Dim LastColumn2 As Long
    Dim StartCell2 As Range
    Set sht2 = Worksheets("Sheet1")
    Set StartCell2 = Range("B11")
    Worksheets("Sheet1").UsedRange
    LastRow2 = sht2.Cells.Find("*", SearchOrder:=xlByRows, SearchDirection:=xlPrevious).Row
    LastColumn2 = StartCell.SpecialCells(xlCellTypeLastCell).Column
    sht2.Range(StartCell2, sht2.Cells(LastRow2, LastColumn2)).Select

    With ActiveWorkbook.Worksheets("Sheet1").Sort
        '.SetRange(StartCell2, sht2.Cells(LastRow2, LastColumn2)).Select
        '.SetRange(StartCell2, sht2.Cells(LastRow2, LastColumn2)).Select
        '.SetRange Range("B11", LastRow2)
        .SetRange Range("B11:AA" & LastRow2)
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

Thanks.

How to&Answers:

You should take a look at these functions. I use them quite often, and they are saved in my Personal Workbook for quick and easy referencing.

Function lastRow(ws As Worksheet, Optional col As Variant = 1) As Long
    With ws
        lastRow = .Cells(.Rows.Count, col).End(xlUp).Row
    End With
End Function

Function LastColumn(ws As Worksheet, Optional rowNum As Long = 1)
    With ws
        LastColumn = .Cells(rowNum, .Columns.Count).End(xlToLeft).Column
    End With
End Function

In conjunction with the above functions, you could use this

Dim ws As Worksheet
Dim sortRng As Range, rngL As Range, rngJ As Range
Dim lstRow As Long
Set ws = ThisWorkbook.Worksheets("Sheet1")
lstRow = lastRow(ws, "J")

With ws

    Set sortRng = .Range("B11", .Cells(lstRow, LastColumn(ws, 11)))
    Set rngJ = .Range("J11:J" & lstRow)
    Set rngL = .Range("L11:L" & lstRow)

    With .Sort
        .SortFields.Clear
        .SortFields.Add Key:=rngJ, SortOn:=xlSortOnValues, Order:=xlAscending, _
                CustomOrder:="AmEx,Discover,Master Card,Visa,Check", DataOption:=xlSortNormal
        .SortFields.Add Key:=rngL, SortOn:=xlSortOnValues, Order:=xlDescending, _
                DataOption:=xlSortNormal
        .SetRange sortRng
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With

End With

Take note: No use of .Select anywhere in the above code. Start with this and learn to avoid using select, as it’s rarely necessary.


Breaking down the code

You will set your entire sort area using this line:

Set sortRng = .Range("B11", .Cells(lstRow, LastColumn(ws, 11)))

These lines are the ranges of the specific columns you are wanting to sort.

Set rngJ = .Range("J11:J" & lstRow)
Set rngL = .Range("L11:L" & lstRow)

Make sure that you clear any prior criteria

.SortFields.Clear

Then add your criteria (your custom sort, for example)

.SortFields.Add Key:=rngJ, SortOn:=xlSortOnValues, Order:=xlAscending, _
    CustomOrder:="AmEx,Discover,Master Card,Visa,Check", DataOption:=xlSortNormal
.SortFields.Add Key:=rngL, SortOn:=xlSortOnValues, Order:=xlDescending, _
        DataOption:=xlSortNormal