CustomOrder上的VBA类型不匹配

时间:2014-03-12 23:40:31

标签: vba

我有这个很好的代码:

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

我正在尝试使用名为keyRange的变量为CustomOrder:=修改上述代码:

Sub NewSortTest()
    Dim keyRange As String

    keyRange = "alpha,bravo,charlie,delta,echo,foxtrot,golf,hotel,india,juliet"

    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

但是我收到类型不匹配错误。 我在MSDN中可以看到CustomOrder:=的类型为Variant。我尝试过Variant而不是String,但我得到了同样的错误。

修改: CustomOrder实际上是SortField类型。 如何将String keyRange转换为SortField对象?

4 个答案:

答案 0 :(得分:5)

很高兴你明白了。以下也适用(每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

修改:更简单

CustomOrder:=CVar(keyRange)

编辑:为什么会这样?

我一直试图弄清楚自己。正如您在搜索中发现的那样,CustomOrder属性上的帮助文档没有任何内容。我一直在尝试不同的事情,看看我是否能得到答案,而且我没有多少运气。我认为CustomOrder在后​​台做了一些魔术。正如您所发现的,它与String字面值或Long一样好。并且String正确演员为Variant并没有问题。但它不喜欢String个变量。它必须与String变量作为引用类型有关。我不知道为什么它无法解决这个问题,但我也不知道它是如何从String文字中动态创建自定义列表的。如果您发现任何可以解释它的内容,我很乐意知道。

答案 1 :(得分:3)

我解决了这个问题。 您需要使用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

答案 2 :(得分:1)

我知道这是一个旧线程,但认为我的方法似乎值得分享。

我将SortField存储为变量,然后按如下所示设置CustomOrder属性,看来编译器将采用定界的字符串并将其转换为所需的字符串。仅供参考loNewReport是一个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

答案 3 :(得分:0)

我仔细查看了使用函数来填充自定义订单字符串,如上一个答案中所示。

我首先忽略它,然后才意识到这可能有效,因为它返回一个文字字符串而不是一个普通的字符串。

无论如何,它起作用,感谢以前的响应者。这就是我想出来解决我的问题。 keyRange符合.SortFields.Add字符串,如前面的回复所示。

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