Best code to sort a table column in a VBA macro

JenniferMurphy

Well-known Member
Joined
Jul 23, 2011
Messages
2,534
Office Version
  1. 365
Platform
  1. Windows
I am working on a macro that will do some processing on the data in a table. When it is done, it might want to sort the table on one column. Having no idea how to do that, I recorded 3 macros with different portions of the table column selected.

This was my first try. I selected one cell in the column.
VBA Code:
Sub Macro1()

' Recorded with one cell in column selected

    Range("D15").Select
    ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort.SortFields. _
        Clear
    ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort.SortFields. _
        Add2 Key:=Range("D15:D22"), SortOn:=xlSortOnValues, Order:=xlDescending, _
        DataOption:=xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

This was my second try. I selected the column header.
Code:
Sub Macro2()

' Recorded with column header selected

    Range("TblExample[[#Headers],[WtdRtg]]").Select
    ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort.SortFields. _
        Clear
    ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort.SortFields. _
        Add2 Key:=Range("TblExample[[#Headers],[#Data],[WtdRtg]]"), SortOn:= _
        xlSortOnValues, Order:=xlDescending, DataOption:=xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

This was my third try. I selected the entire column, but not the header. This looks like the best option. But do I need all of that code?
Code:
Sub Macro3()

' Recorded with entire column (without header) selected

    Range("TblExample[WtdRtg]").Select
    ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort.SortFields. _
        Clear
    ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort.SortFields. _
        Add2 Key:=Range("TblExample[WtdRtg]"), SortOn:=xlSortOnValues, Order:= _
        xlDescending, DataOption:=xlSortTextAsNumbers
    With ActiveWorkbook.Worksheets("Example").ListObjects("TblExample").Sort
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
End Sub

Thanks for any help.
 

Excel Facts

Add Bullets to Range
Select range. Press Ctrl+1. On Number tab, choose Custom. Type Alt+7 then space then @ sign (using 7 on numeric keypad)
Among the three codes you provided, "Macro3" can be considered the most dynamic.
- Macro3 operates on a specific column ("WtdRtg") of the table ("TblExample"), without relying on a fixed range or number of rows. It selects the entire column dynamically based on the table's structure. This allows the code to adapt to changes in the size or location of the data within the column.
- The code uses structured references ("TblExample[WtdRtg]") instead of hardcoded cell references. Structured references in Excel tables are dynamic and adjust automatically when the table size or structure changes. This enhances the flexibility and adaptability of the code.
- By using the "Range" object's dynamic selection based on the table structure, the code can handle varying data sizes and adapt to changes in the table's layout without requiring manual adjustments to the code.
If put it in worksheet_change event, table will be sorted instantly, no subrourtine activate
 
Upvote 0
As far as minimal code goes, and using your Macro3 as the basis, try the following:
VBA Code:
Sub JMurph()
    With Worksheets("Example").ListObjects("TblExample").Sort
        .SortFields.Clear
        .SortFields.Add Key:=Worksheets("Example").Range("TblExample[WtgRtg]"), Order:=2
        .Header = xlYes
        .Apply
    End With
End Sub
 
Upvote 0
As far as minimal code goes, and using your Macro3 as the basis, try the following:
VBA Code:
Sub JMurph()
    With Worksheets("Example").ListObjects("TblExample").Sort
        .SortFields.Clear
        .SortFields.Add Key:=Worksheets("Example").Range("TblExample[WtgRtg]"), Order:=2
        .Header = xlYes
        .Apply
    End With
End Sub
I like the compactness. Is there anything that could go wrong that this code does not catch that the more elaborate code does? I like tight code, but I like correct results even better! Thanks
 
Upvote 0
Is there anything that could go wrong that this code does not catch that the more elaborate code does?
I don't believe so, it's very specific as far as capturing the ranges/columns involved - although it would take significant testing to try to crash it (perhaps with different data types in the WtgRtg column?).
 
Upvote 0
I don't believe so, it's very specific as far as capturing the ranges/columns involved - although it would take significant testing to try to crash it (perhaps with different data types in the WtgRtg column?).
The data in the WtdRtg column will always be numeric (z scores). That column is the result of (output from) the macro. The numbers will typically range from +100 to -300.
 
Upvote 0
Should be fine then. Some of your code in Macro3 (e.g. .SortMethod = xlPinYin) are the default values for Sort anyway & don't necessarily need to be specified.
 
Upvote 0
Should be fine then. Some of your code in Macro3 (e.g. .SortMethod = xlPinYin) are the default values for Sort anyway & don't necessarily need to be specified.
Your code gets a run-time error '1004' on the second sortfields statement.

1684907615534.png


Here's the code.

VBA Code:
  With Worksheets("Example").ListObjects("TblExample").Sort
    .SortFields.Clear
    .SortFields.Add Key:=Worksheets("Example").Range("TblExample[WtgRtg]"), Order:=2
    .Header = xlYes
    .Apply
  End With

Bebo's code works.
 
Upvote 0
Your code gets a run-time error '1004' on the second sortfields statement.
Strange, because it worked on a mock-up table I created based on what your Macro 3 code refers to (sheet & table names).
Before:
Book1
ABC
1HDR1WtgRtgHDR3
2242
3313
4444
5575
6686
7767
Example


After:
Book1
ABC
1HDR1WtgRtgHDR3
2686
3575
4767
5242
6444
7313
Example


If you could provide your actual sheet using the XL2BB - Excel Range to BBCode, or share it via Dropbox, Google Drive or similar, I'd like to discover what's causing the problem. :)
 
Upvote 0
Here's the minisheet. The macro is in an add-in module.

Weighted Ratings.xlsx
ABCDEFGH
3Table nameTblExample
4Maximum Final Rating
5Sort on WtdRtg?
6Number of products10
7
8Header SyncPriceRank0-10 Rtg1-5 Rtg
9Data TypeNumNumNumNum
10Rating OrderLoHiLoHiHiLoHiLo
11Weight321
12ProductProd RankWtdRtgPriceRank0-10 Rtg1-5 Rtg
13B1+100.00$30019.7
14D3+75.24$35019.9
15A2+84.78$25069.8
16F5+23.50$40039.9
17C4+32.79$30079.5
18E6-12.32$35089.4
19H7-32.16$45039.2
20J8-77.52$50038.8
21I10-109.42$450109.0
22G9-84.90$40098.5
23Mean-0.00$3755.19.4
24Std Dev-75.17
Example
Cell Formulas
RangeFormula
D6D6=COUNTA(TblExample[Product])
E8E8=TblExample[[#Headers],[Price]]
F8F8=TblExample[[#Headers],[Rank]]
G8G8=TblExample[[#Headers],[0-10 Rtg]]
H8H8=TblExample[[#Headers],[1-5 Rtg]]
C13:C22C13=RANK.EQ([@WtdRtg],[WtdRtg],0)
E23E23=SUBTOTAL(101,[Price])
F23F23=SUBTOTAL(101,[Rank])
G23G23=SUBTOTAL(101,[0-10 Rtg])
D23D23=SUBTOTAL(101,[WtdRtg])
D24D24=-STDEV.S(TblExample[WtdRtg])


I'm going to bed. More on this tomorrow.
 
Upvote 0

Forum statistics

Threads
1,215,150
Messages
6,123,312
Members
449,094
Latest member
Chestertim

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