2017-02-23 58 views
3

想更好地了解如何比较对象类型的键。 dicOverall.exists(dic2)返回FalsedicOverall.exists(dic1)返回True。我不太确定.Exists比较东西(循环?),但是有无论如何,我可以得到.Exists(dic2)返回True?谢谢!Excel VBA - Dictonary.Exists(Dictionary)?

Sub test() 
    Dim dic1 As Object 
    Dim dic2 As Object 
    Dim dicOverall As Object 


    Set dic1 = CreateObject("scripting.dictionary") 
    Set dic2 = CreateObject("scripting.dictionary") 
    Set dicOverall = CreateObject("scripting.dictionary") 

    dic1("Hi") = 1 
    dic1("Hello") = 1 

    dic2("Hi") = 1 
    dic2("Hello") = 1 

    dicOverall(dic1) = 1 

    Debug.Print dicOverall.exists(dic2) 


End Sub 
+0

你必须先DIC2添加到dicOverall,在此之前,它显然没有按不存在于dicOverall中 – gizlmo

+0

您需要将该密钥添加到dic2,这就是Exists正在检查的内容。 – SJR

+0

添加此行:'dicOverall(dic2)= 1' –

回答

4

我想,如果你这样做

dicOverall(dic1) = 1 

然后在dicOverall现有的唯一关键是对象dic1,你问,如果存在dicOverall关键dic2?这个答案不能是true它总是false

dic1dic2是2个完全不同的对象,即使它们包含相同的键。 .exists不比较这些对象的内容,它只是看到这些对象是不同的对象。

例子:
比方说.exists检查是否有具体的目标是在一个盒子里,你有2个苹果称为dic1dic2。如果你把苹果dic1放入盒子,并检查.exists如果苹果dic2是在框中,你会得到一个没有。 .exists不检查是否有苹果在框中检查是否有具体苹果名为dic2是在框中。即使它们都是苹果,看起来也一样。

Sub AppleExample() 
    Dim apple1 As Object 
    Dim apple2 As Object 
    Dim box As Object 

    Set apple1 = CreateObject("scripting.dictionary") 
    Set apple2 = CreateObject("scripting.dictionary") 
    Set box = CreateObject("scripting.dictionary") 

    'apple1 has 1 stem and a red color 
    apple1("stem") = 1 
    apple1("redColor") = 1 

    'apple2 has 1 stem and a red color 
    apple2("stem") = 1 
    apple2("redColor") = 1 

    'put apple1 into the box 
    box(apple1) = 1 

    'check if apple2 is in the box 
    Debug.Print box.exists(apple2) 
End Sub 

如果你想检查是否有东西在盒子,看起来像apple1但实际上是apple2那么你必须检查所有属性(干,颜色,...)自己。


如果你想检查是否dic1具有相同的密钥为dic2,那么你必须检查...

  1. 如果dic1dic2具有键(必要的相同的计数,如果dic2具有从所有键dic1但加上其他密钥!)
  2. 如果第一个是真的,然后遍历所有密钥dic1并检查每个单个密钥是否存在dic2

下面是关于字典一个很好的资源:VBA DictionaryUsing the Dictionary Class in VBA

+0

嘿,这正是我想要实现的 - 比较每个字典的关键字。我有这样一个问题的原因是,假设我有'apple1 =“red”'和'apple2 =“red”',那么2个独立的变量应该有不同的内存地址。但是,如果我要做'dic(apple1)= 1'和随后的'dic.Exists(apple2)',我相信我应该得到'真实'。通过这个扩展,我想知道是否有一种简单的方法通过利用'.Exists'方法来比较2个数组或字典。 – AiRiFiEd

+0

不,比较2个字典的内容是不可能的,就像你尝试过的那样。因此,您必须像我在答案的最后部分所显示的那样遍历字典。 'dic.Exists(apple2)'如果在'dic'中只有'apple1',即使它们都是红色,也不会**为'true'。 –

+0

道歉混淆 - 在上面的评论中'apple1'和'apple2'是字符串而不是对象。我想知道是否'.Exists'工作2个字符串变量(具有不同的内存地址),为什么不能用于2个对象?由于没有为对象工作已经被证明,'.Exists'究竟是什么比较?感谢您对此查询的耐心等待!编辑:'apple1 =“red”''apple2 =“red”''dicOverall(apple1)= 1''Debug.Print dicOverall.Exists(apple2)' – AiRiFiEd

1

我能想到的唯一办法让.Exists(dic2)返回True是设置dic2dic1 - 所以在引擎盖dic1dic2只是指向相同的基础对象。

然后 - 即使你永远不会做dicOverall.Add dic2, 1如果你做dicOverall.Exists(dic2),你仍然会得到True

这完全是缺乏现实生活中的应用程序 - 但如果你正在玩字典的话很有用。在这个示例代码中,您将看到使用Set dic2 = dic1使它们指向相同的底层字典。而改变dic2的值也会改变它在dic1--显示它们是指向同一事物的指针。

那么对于dic2检查所的dicOverall一键返回True

Option Explicit 

Sub Test() 

    Dim dic1 As New Dictionary 
    Dim dic2 As New Dictionary 
    Dim dicOverall As New Dictionary 

    'add items to first dictionary 
    dic1.Add "foo", "bar" 
    dic1.Add "baz", "qux" 
    'make second refer to first 
    Set dic2 = dic1 
    'add first dictionary to overall 
    dicOverall.Add dic1, 1 

    'change a value in 2nd dictionary and see 1st dictionary change too 
    Debug.Print dic1.Item("baz") 
    dic2.Item("baz") = "hello world" 
    Debug.Print dic1.Item("baz") 

    'shows 1 for both dictionaries 
    '*even though you never added dic2 to dicOverall* 
    Debug.Print dicOverall.Exists(dic1) 
    Debug.Print dicOverall.Exists(dic2) 

End Sub 

我调试输出:

qux 
hello world 
True 
True 
+0

但是当你这样做,并添加一个'dic1'的密钥,它也会被添加到'dic2'。那么你只有2个名字,不是吗? –

+0

是的。在我的回答中,“dic1”和“dic2”是指向同一字典的指针。它是对这个问题的回答,但是很难想象为什么你会在现实生活中应用它。否则,OP问题只会得到答案'否 - 您需要将'dic2'添加到'dicOverall''。你对字典看起来相同但不相同的观点与我的回答相反,我实际上*使它们相同* –

+0

是的,这也是我的想法。你是对的。我只是认为OP认为'.exists'检查'dic2'中是否存在'dic1'的所有关键字。只是想确保差异是明确的。在你的例子中,'dic1'和'dic2' **是相同的**,在例子中'dic1'和'dic2' **具有相同的内容但是不同的对象**。 –