VBA Type Mismatch on CustomOrder

后端 未结 4 740
情歌与酒
情歌与酒 2020-12-11 05:12

I have this code which works great:

Sub NewSortTest()
    ActiveWorkbook.Worksheets(\"Sheet1\").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets(\"Sheet1\         


        
相关标签:
4条回答
  • 2020-12-11 05:38

    I worked it out. You need to use a ListArray:

    Sub NewSortTest()
        Dim keyRange As Variant
        Dim sortNum As Long
    
        keyRange = Array("alpha", "bravo", "charlie", "delta", "echo", "foxtrot", "golf", "hotel", "india", "juliet")
    
        Application.AddCustomList ListArray:=keyRange
        sortNum = Application.CustomListCount
    
        ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
        ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add key:=Range("A1:A20"), SortOn:=xlSortOnValues, Order:=xlAscending, CustomOrder:=sortNum, DataOption:=xlSortNormal
        With ActiveWorkbook.Worksheets("Sheet1").Sort
            .SetRange Range("A1:B20")
            .Header = xlGuess
            .MatchCase = False
            .Orientation = xlTopToBottom
            .SortMethod = xlPinYin
            .Apply
        End With
    End Sub
    
    0 讨论(0)
  • 2020-12-11 05:41

    I looked carefully at using a function to populate the custom order string as shown in a previous answer.

    I ignored it at first before realising that this probably works because it is returning a literal string not an ordinary string.

    Anyway it works so thanks to previous responders. THis is what I came up with to solve my problem. keyRange fits into the .SortFields.Add string as demonstrated by the previous replies.

    Function keyRange() As String
        'Create a string used to sort data on another sheet.
        'Becomes part of the .SortFields.Add statement as CustomOrder:=keyfield
        'CustomOrder items are in Col "A" of a sheet. The list can change over time
        'and is refreshed from an import from a database.
        With Sheets("Home Groups")
            lic = lastInCol(.Range("A1"))       'Gets the last used cell in column A
                                                'lastInCol is one of John Walkenbach's routines
                                                'From his book Excel 2010 Power Programming with VBA
           'Create a string from those items from row 2 to the last used row
            For rw = 2 To lic
                If rw = 2 Then
                    keyRange = .Cells(rw, 1)        'This is the first item
                Else
                    keyRange = keyRange & "," & .Cells(rw, 1)   'The remaining items - comma separated
                End If
            Next rw
        End With
    End Function 
    
    0 讨论(0)
  • 2020-12-11 05:46

    I know this is an old thread but figured my approach seems worth sharing.

    I stored the SortField as a variable then set the CustomOrder property as per below, it seems the complier will take the delimited string and convert it to whatever it requires. FYI loNewReport is a ListObject

    Dim sField As SortField
    Set sField = loNewReport.Sort.SortFields.Add(loNewReport.ListColumns("Branch").DataBodyRange, xlSortOnValues, xlAscending)
    sField.CustomOrder = "QLD, NSW, VIC"
    loNewReport.Sort.Apply
    Set sField = Nothing
    
    0 讨论(0)
  • 2020-12-11 05:52

    Glad you figured it out. The following also works (per this post):

    Sub NewSortTest()
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Clear
    ActiveWorkbook.Worksheets("Sheet1").Sort.SortFields.Add Key:=Range("A1:A20"), _
                                                            SortOn:=xlSortOnValues, _
                                                            Order:=xlAscending, _
                                                            CustomOrder:=keyRange, _
                                                            DataOption:=xlSortNormal
    With ActiveWorkbook.Worksheets("Sheet1").Sort
        .SetRange Range("A1:B20")
        .Header = xlGuess
        .MatchCase = False
        .Orientation = xlTopToBottom
        .SortMethod = xlPinYin
        .Apply
    End With
    End Sub
    
    Function keyRange() As String
    
    keyRange = "alpha,bravo,charlie,delta,echo,foxtrot,golf,hotel,india,juliet"
    
    End Function
    

    Edit: Even easier

    CustomOrder:=CVar(keyRange)
    

    Edit: Why Does This Work?

    I've been trying to figure that out myself. The help documentation on the CustomOrder property lacks any meat, as you found out in your search. I've been experimenting with different things to see if I could get at an answer, and I haven't had much luck. I think CustomOrder is doing some magic in the background. It does just fine with a String literal or a Long, as you found out. And it has no poblem with a String properly cast as Variant. But it doesn't like String variables. It must have something to do with String variables being reference types. I have no idea why it wouldn't be able to handle that, but I also don't know how it creates a custom list on the fly from a String literal. If you find anything that explains it, I'd love to know.

    0 讨论(0)
提交回复
热议问题