为什么字典键不能成为单元格?

时间:2017-01-10 15:25:15

标签: vba excel-vba excel

我遇到了更复杂的代码问题而我还没有完全理解字典,所以我构建了一个非常简单的基本测试表来弄清楚它们是如何工作的。在a-c列的顶部只有三个条目,读取“first”,“do”和“alpha”(目标是最终确保我理解嵌套字典,但无论如何这个问题都没有进入)。

代码是:

Sub testing()

Dim dict As New Scripting.Dictionary

dict.Add Key:=Cells(1, 1), Item:=Cells(1, 2)
MsgBox dict(Cells(1, 1))

End Sub

这不起作用。但是当我添加变量temp = Cells(1, 1)并在其出现的任何地方使用它代替Cells(1, 1)时,它就起作用了。

为什么键不能成为单元格?有人可以帮我理解

之间的区别
dict.Add Key:=Cells(1, 1), Item:=(1, 2)

temp = Cells(1, 1)

dict.Add Key:=temp, Item:=(1, 2)

是?该项目可以是一个单元格,而不是关键?

1 个答案:

答案 0 :(得分:0)

可以使用对象作为键和值(包括.Cells返回的范围),如此代码所示:

Public Sub Example()
    Dim dict As New Scripting.Dictionary
    dict.Add Sheet1.Cells(1, 1), Sheet1.Cells(1, 1)
    dict.Add Sheet1.Cells(1, 2), Sheet1.Cells(1, 1)

    Dim x As Variant
    For Each x In dict.Keys
        Debug.Print TypeName(x) 'Prints Range
    Next

    For Each x In dict.Items
        Debug.Print TypeName(x) 'Prints Range
    Next
End Sub

事实上,您上面的代码“有效” - 您只是没有在MsgBox中看到您的期望。在这行代码......

MsgBox dict(Cells(1, 1))

... MsgBox的第一个参数是Variant,但它最终需要能够显示String。如果它接收一个对象作为参数,则会调用其默认成员(在本例中为.Value)。这意味着您的代码等同于:

MsgBox dict(Cells(1, 1).Value)

对于使用temp的第二个示例,我假设它未声明(并且隐式Variant)或其他一些强类型值。在这种情况下,赋值隐式调用Cells(1, 1)的默认成员,因此您的赋值等同于:

Dim temp As Variant
temp = Cells(1, 1).Value
dict.Add temp, Cells(1, 2)  '<--- temp is whatever the type of Cells(1, 1).Value is.

如果将temp声明为Range(或Object),则其工作方式与上面的Sub Example()完全相同:

Dim temp As Range
Set temp = Cells(1, 1)
dict.Add temp, Cells(1, 2)    '<--- temp is a Range.

请注意,唯一的单元格与唯一的单元格对象不同:

Public Sub Example2()
    Dim dict As New Scripting.Dictionary
    Cells(1, 1).Value = "Foo"
    Cells(1, 2).Value = "Foo"

    'This is fine - the keys are unique cell references:
    dict.Add Cells(1, 1), Empty
    dict.Add Cells(1, 2), Empty   '<-- No runtime error

    Set dict = New Scripting.Dictionary

    'This is an error - the keys are identical values:
    dict.Add Cells(1, 1).Value, Empty
    dict.Add Cells(1, 2).Value, Empty  '<-- Runtime error 457, key already exists.
End Sub