VBA-字典搜索-类型不匹配

时间:2018-06-27 05:46:17

标签: excel vba dictionary type-mismatch

所以我正在学习如何使用字典,但是遇到类型问题。在下面的代码中,我得到一个错误。

  

类型不匹配

每次我尝试致电If Not target.SearchItem(sKey) Is Nothing Then。我希望它返回一个对象,如果不是Nothing,我可以将其转换回long。

For Each target In dList.getArray
    For Each key In aList.getArray(1).getKeys
        sKey = CStr(key)
            'Error occurs here - as Type mismatch
            If Not target.SearchItem(sKey) Is Nothing Then
                cData.setData(sKey) = CLng(target.SearchItem(sKey))
                target.removeData = sKey
             Else
                 'if value doesn't exists it will just be 0
                  cData.setData(sKey) = 0
              End If
    Next key
Next target

data是我的字典,它在单独的类中:

Property Get SearchItem(name As String) As Variant
    If data.exists(name) Then
        'becomes a Variant/Integer - data(name) is a Variant/long
        Set SearchItem = CVar(data(name))
    Else
        'Should return Nothing if item doesnt exist
        Set SearchItem = Nothing
    End If
End Property

更新:为了解释这个问题,我介绍了更多。即使我将其作为变体形式返回,它仍将部分为Integer,因此,如果Not target.SearchItem(sKey) Is Nothing Then将返回不匹配项,因为它需要一个对象并且VBA不会将其作为变体之类。有没有什么比它更有效的了?这样可以解决问题。

下面的这段代码返回的时间很长,但是我不能使用-99,因为它会破坏数据分析。它应该是没有价值的东西

Property Get SearchItem(name As String)
    If data.exists(name) Then
        SearchItem = data(name)
    Else
        'SearchItem = Nothing
         SearchItem = -99
    End If
End Property

3 个答案:

答案 0 :(得分:1)

  1. If Not target.SearchItem(sKey) Is Nothing Then
    • 这意味着存储的项目是一个对象
  2. cData.setData(sKey) = CLng(target.SearchItem(sKey))
    • 此行在对象上起作用的唯一方法是该对象具有可以转换为long的默认值。如果对象的默认值返回的值可以转换为long。

Clng(Object)是否对存储在字典中的实际对象起作用?

如果要存储混合数据类型,则SearchItem检查返回数据是否为对象。

Property Get SearchItem(name As String) As Variant
    If isObject(data(name)) Then
        Set SearchItem = data(name)
    Else
        SearchItem = data(name)
    End If
End Property

我不会在此方法中转换数据类型。相反,我将创建一个或多个单独的方法或在使用时转换数据类型。

Function getTypedItem(Key as Variant, DataType as VbVarType) as Variant

IsNumeric(Obj)

由于您使用的是词典的实际键,我们知道它会返回某些内容,因此在这种情况下不需要.Exists。您需要做的是在测试是否Object Is Nothing之前先测试它是否返回对象。

If IsObject(Target.SearchItem(sKey)) Then
    If IsNumeric(Target.SearchItem(sKey)) Then
        cData.setData(sKey) = CLng(Target.SearchItem(sKey))
    End If
ElseIf IsNumeric(Target.SearchItem(sKey)) Then
    cData.setData(sKey) = CLng(Target.SearchItem(sKey))
End If

答案 1 :(得分:0)

我认为您不能使用Set来分配整数,因此当字典项是Integer时,该属性将失败。也许使用:

Property Get SearchItem(name As String) As Variant
    If data.exists(name) Then
        'becomes a Variant/Integer - data(name) is a Variant/long
        SearchItem = data(name)
        ...

答案 2 :(得分:0)

不幸的是,VBA没有可空的原始类型,例如可空的Long。通常的解决方法是使用Variant,该Variant可以被赋予Empty的值,也可以在本地保留Long。

我将按如下方式重写您的财产:

Property Get SearchItem(name As String) As Variant
    If Data.exists(name) Then
        SearchItem = Data(name)
    Else
        SearchItem = Empty
    End If
End Property

对于空的测试将是:

If Not IsEmpty(target.SearchItem(sKey)) Then ...