查找与字典中的项对应的键

时间:2012-01-27 04:08:40

标签: vba dictionary excel-vba excel

有没有办法找到与VBA字典中给定项目对应的密钥?

http://msdn.microsoft.com/en-us/library/aa164502%28v=office.10%29.aspx MSDN建议可以使用“Key”属性,但是当我尝试使用它时,我收到一个错误(“编译错误:无效使用属性”)。我在过去发现这里给出的“存在”方法对我来说也不起作用,所以我认为它们是以前版本的Office中的命令,现在已经过时了。但是,我无法找到最新版Office的等效文件。

我可以使用a为每个循环创建一个新词典,其中旧词典中的键是新词典中的项目(反之亦然),然后使用“.Item”,但我想知道是否有内置命令,可以让我避免这种情况。

4 个答案:

答案 0 :(得分:10)

  
    
      

但我想知道是否有一个内置命令可以让我避免这种情况。

    
  

没有内置命令。你将不得不求助于某种循环。这是一个例子。我创建了一个小函数来获取对应于字典中项目的键。

Dim Dict As Dictionary

Sub Sample()
    Set Dict = New Dictionary

    With Dict
      .CompareMode = vbBinaryCompare
      For i = 1 To 10
        .Add i, "Item " & i
      Next i
    End With

    Debug.Print GetKey(Dict, "Item 3")
End Sub

Function GetKey(Dic As Dictionary, strItem As String) As String
    Dim key As Variant
    For Each key In Dic.Keys
        If Dic.Item(key) = strItem Then
            GetKey = CStr(key)
            Exit Function
        End If
    Next
End Function

答案 1 :(得分:2)

备用解决方案(..?)

不是通过字典中的每个项目进行匹配,而是如何维护2个字典对象?第二个,使用值作为键,键作为其值。当你添加一个项目时,你将它添加到词典中。如果你有一把钥匙,你可以在第一本词典中查找它,如果你有这个值,你可以在第二本词典中查找。

答案 2 :(得分:0)

实际上,有一种Exists方法可以完全按照您的要求进行操作。以下是它的工作原理:

...
Dim dict
Set dict = CreateObject("Scripting.Dictionary")
dict.Add "utensil", "spork"
Debug.Print dict.Exists("utensil")

以上返回True。

答案 3 :(得分:0)

由此,我首先想到.exists(key)是完全没用的。 但是容易规避。

首先,让我提一下徒劳的尝试:

  1. 确保第一次引用要检查的值时,指定 .exists(key)到布尔变量。
  2. 如果该布尔值为FALSE,则立即删除字典
    您在测试密钥时无意中创建的条目
  3. 嗯,这样可行,但下次再使用此代码测试存在时

    itExists = a.exists(key) 
    

    你可能会收到424错误 - .exists的实现者真的失败了。但是以下工作(或者至少,对我而言......到目前为止)

    if isempty(a.item(key)) then  ' checking on value of the object
      a.remove(key)
      a.add key, value
    else ' you have a key duplicate
      ' do something about dupe, like quit
    end if 
    

    稍微澄清一下,您可以查看下面的示例代码


    Sub aDict()
    Dim a As Dictionary
    Dim x As Long
    Set a = New Dictionary
    With a
      On Error Resume Next
    ' first add
      .Add 1, "sumpn"
    ' second add
      .Add "dog", "beagle"
      x = 66
    ' third add
      .Add "sixty", x
      printd a, 1, "added with numerical key"
      printd a, 2, "added with string key = dog, using numeric key=2"
      Stop    ' look at count of items: we added 3, but have 4 in local vars
      printd a, "2", "searching string key '2', not retrieving 2nd added"
      printd a, 9, "should not exist, first try"
         ' but the .exists has created it!!
      printd a, 9, "should not exist, second try, *** but now created ***"
      printd a, 8, "never seen anywhere"
    Stop    ' look at a in local vars!! #8 exists now as item 7
      a.Remove 8  ' so we kill it
    ' *************************** the great fixit *******  
    Stop    ' observe that #8 (item 7) is gone again
      printd a, "dog", "added as second position (Item 2)"
    ' fourth add
      .Add 1, "else" ' doublette
      printd a, 1, "position 1 is taken, Err=457 is correct"
    ' fifth add
      .Add 3, "beagle"
      printd a, "3", "string key='3' <> numeric 3"
    ' 6th add
      .Add 5, "beagle"
      printd a, "beagle", "value is already there with key 'dog'"
      printd a, 5, "numeric key=5"
    End With
    End Sub
    
    Sub printd(a As Dictionary, mkey, Optional msg As String)
    Dim ex As Boolean
    With a
      If Err.number <> 0 Then
          Debug.Print mkey, "error " & Err.number, Err.Description
      End If
    Err.clear
      ex = .Exists(mkey) ' very first reference to a.Exists(mkey)
      Debug.Print "key " & mkey, "a(" & mkey & ")" & a(mkey), _
                  "Exists", ex, "a.item " & .Item(mkey), msg
      If Err.number <> 0 Then
        Debug.Print mkey, "error " & Err.number, Err.Description
      End If
    End With
    End Sub