Question

What I'm trying to do is select a table in a spreadsheet, and then sort according to 2 different columns

I generated this code with the record macro option. The table changes in size which is why I have used the xlDown, unfortunately the code later references the exact cells "B4:B52". Any idea how I might solve this issue?

Range("B4:J4").Select
Range(Selection, Selection.End(xlDown)).Select
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range( _
    "B4:B52"), SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal
ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range( _
    "G4:G52"), SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
With ActiveWorkbook.Worksheets("Sheet1").Sort
    .SetRange Range("B4:J52")
    .Header = xlGuess
    .MatchCase = False
    .Orientation = xlTopToBottom
    .SortMethod = xlPinYin
    .Apply
End With
Was it helpful?

Solution

Since you are sorting a Table (ListObject in VBA), you'll want to refer to it. This will dynamically adjust to encompass entire table columns. In this example the column headers/names to be sorted are "Data1" and "Data3":

Sub SortTable()
Dim lo As Excel.ListObject

'change this assignment to suit your table location and name
Set lo = ActiveWorkbook.Worksheets("Sheet1").ListObjects("Table1")
With lo
.Sort.SortFields.Clear
    .Sort.SortFields.Add _
        Key:=Range("Table1[data1]"), SortOn:=xlSortOnValues, Order:=xlAscending, _
        DataOption:=xlSortNormal
    .Sort.SortFields.Add _
        Key:=Range("Table1[data3]"), SortOn:=xlSortOnValues, Order:=xlAscending, _
        DataOption:=xlSortNormal
    With .Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End With
End Sub

OTHER TIPS

I would sort the column in the table in the following way:

Sub SortingTable()
Dim ws As Worksheet
    set ws = ActiveSheet
Dim target_table As ListObject
    Set target_table = ws.ListObjects(wsName)
Dim sort_column_index As Long
    sort_column_index = target_table.ListColumns("ColumnToBeSortedName").Index
Dim sort_column As Range
    Set sort_column = target_table.ListColumns(sort_column_index).Range

' Applying the sorting to the table
With target_table.Sort
    .SortFields.Clear
    .SortFields.Add Key:=sort_column _
        , SortOn:=xlSortOnValues, Order:=xlAscending _
        , DataOption:=xlSortNormal
    .Apply
End With    
End Sub

In fact, the only difference is that you declare a Range and assign it to the specific table column that should be sorted. Doing it this way, you're able to apply the macro to tables on different sheets assuming that the tables contain the column with name "ColumnToBeSortedName".

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top