将Variant设置为集合项始终返回错误

时间:2016-01-14 12:57:00

标签: vba excel-vba excel

上下文

我有一个自定义函数,其范围是输入一定范围的值(即可能重复的字符串列表,例如"EUR/USD""USD/BRL""EUR/USD"并输出类似SQL的字符串,如下所示:

not in ('EUR/USD', 'USD/BRL' ... )

由于电子表格中的值可能会重复,因此在进行任何解析之前,我尝试创建一组唯一值(例如,如果EUR/USD在电子表格中出现4次,我只会希望它一次出现在我的收藏中。

为了达到这个目的,我开发了这个简单的功能:

Public Function NOT_IN_SQL(ByVal values As Range) As String

    'parse list (get uniques only)
    Dim uniquesCollection As New Collection
    Dim rng As Range

    For Each rng In values

        If Not inCollection(uniquesCollection, rng.Value) Then
            uniquesCollection.Add rng.Value
        End If

    Next rng

    NOT_IN_SQL = "tmp crap value"

End Function

您可以注意到,If块决定是否向集合添加特定值正在使用另一个自定义函数inCollection,定义如下:

Private Function inCollection(ByVal coll As Collection, ByVal element As String) As Boolean

    Dim var As Variant

    On Error Resume Next
        var = coll.Item(element)
        If Err.Number <> 0 Then
            inCollection = False
        Else
            inCollection = True
        End If
        Set var = Nothing
    On Error GoTo 0

End Function 

此函数基本上尝试将对象var(声明为Variant)设置为collection.Item(),索引为当前分析范围的值。

如果出现错误,则表示在集合中找不到该元素,因此我返回inCollection = False,否则我返回True [我知道它不是一个很好的实现方式,但它是我在VBA中可以想到的最好的尝试捕捉方法]。

问题

然而,似乎我的第二个功能的代码出了问题。 实际上,无论元素是否在集合中,语句都是:

var = coll.Item(element)

将始终引发异常,因此它永远不会告诉我该元素是否在集合中。

测试/调试案例

1)打开Excel电子表格,添加模块并复制/粘贴上述两个功能

2)在任何电子表格的范围A1和A2中,键入值testtest(相同的值)。

3)在范围A3中,在调试模式下插入=NOT_IN_SQL(A1:A2),并将一个观察者添加到对象uniquesCollection,以查看函数末尾的内容。即使我只预期("test","test"),您也会看到它("test")

请注意:我已经进行了第一次分析,如上所述,问题是var = coll.Item(element) 总是引发异常(因此inCollection始终返回{{ 1}}),但我不明白为什么。

有谁可以帮我理解我做错了什么?

1 个答案:

答案 0 :(得分:2)

在函数Foo res = list.OrderByDescending(x => x.Group.Count).FirstOrDefault(); if (res != null) { List<string> longestList = res.Group; } 中,当项目添加到集合时,需要使用密钥。

NOT_IN_SQL

请参阅Add方法文档。