简体   繁体   中英

In a multi-sheet workbook, how do I code a multi-column sort in VBA?

I'm building a cargo stacking calculator in Excel/VBA, and one stage of it separates the stackable cargo into a separate sheet for the actual stacking calculations. As part of that, I need to sort the items by, in order:

  • Cargo type ("Pipes", "Beams", "Plates", other/undefined - a wildcard would be useful, but in theory only those three types should occur)
  • Width (high to low)
  • Length (high to low)

Using the macro recorder to try with an Excel sort, it's all in A1 notation with no sheet defined. I've also tried adding a sheet variable ( wsStackList. ) to the Range element, to no avail. Nor can I seem to make it work with R1C1 notation (tried with Cells(1,2):Cells(2,2) and Cells(1,2), Cells(2,2) but not yet any concatenated or code-based forms) or named ranges ( Range("StackingField") ).

The error message I get at the moment is a 1004 error, specified as "Unable to get the Sort property of the Range class".

My current code for this sub is:

Sub SegmentSort()
' Sort by segment

    Range("StackingField").Sort.SortFields.Add Key:=Range("A2:A501"),_
        SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:="Pipes,Beams,Plates",_
        DataOption:=xlSortNormal
    Range("StackingField").Sort.SortFields.Add Key:=Range("F2:F501"),_
        SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
    Range("StackingField").Sort.SortFields.Add Key:=Range("E2:E501"),_
        SortOn:=xlSortOnValues, Order:=xlDescending, DataOption:=xlSortNormal
    With Range("StackingField").Sort
        .SetRange Range("A1:H501")
        .Header = xlYes
        .MatchCase = False
        .Orientation = xlTopToBottom
        .Apply
    End With

End Sub

Is it worth trying to make this work, or would I be better off going back to basics and trying to code some sort of sort algorithm from scratch in VBA? It's not something I have any experience of, but I know the basic concepts of swap sorts and the like. Definitely far from confident.

I don't know why Dirk Reichel deleted his answer, but it worked a treat! The code he suggested was this:

Sub SegmentSort()
  With Sheets("Stacker").Sort
    .SortFields.Clear
    .SortFields.Add Range("A:A"), xlSortOnValues, xlAscending, "Pipes,Beams,Plates", xlSortNormal
    .SortFields.Add Range("F:F"), xlSortOnValues, xlDescending, , xlSortNormal
    .SortFields.Add Range("E:E"), xlSortOnValues, xlDescending, , xlSortNormal
    .SetRange Range("A:H")
    .Header = xlYes
    .MatchCase = False
    .Orientation = xlTopToBottom
    .Apply
  End With
End Sub

Dirk, I can't give you the upvote you deserve, but thanks!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM