Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/vba/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Vba 为什么可以';字典键不能变成单元格吗?_Vba_Excel - Fatal编程技术网

Vba 为什么可以';字典键不能变成单元格吗?

Vba 为什么可以';字典键不能变成单元格吗?,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

我在处理更复杂的代码时遇到了麻烦,而且我还没有完全理解字典,所以我构建了一个非常基本、简单的测试表来了解它们是如何工作的。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)

是吗?项目可以是单元格,而不是键

您可以使用对象作为键和值(包括
.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的第一个参数是
变量
,但它最终需要能够显示
字符串
。如果它接收一个对象作为参数,它将调用其默认成员(
.Value
)。这意味着您的代码相当于:

MsgBox dict(Cells(1, 1).Value)
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
的第二个示例,我假设它要么是未声明的(并且隐式地是
Variant
),要么是其他一些强类型的值。在这种情况下,赋值隐式调用
单元格(1,1)
的默认成员,因此赋值等价于:

MsgBox dict(Cells(1, 1).Value)
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.
请记住,唯一单元值与唯一单元对象不同:

Public子示例2()
Dim dict作为新的脚本编写字典
单元格(1,1)。Value=“Foo”
单元格(1,2)。Value=“Foo”
'这很好-键是唯一的单元格引用:
添加单元格(1,1),空

dict.添加单元格(1,2),在两个单元格(1,1)的末尾清空“put
。value
”。是的,字典在存储数据时非常方便。没有
Value
its存储范围对象。噢!我没听说过这个功能。因此,
.value
返回一个字符串,其中包含
.value
附加到的任何内容?因此,如果我理解正确-因为我在字典(单元格)中保存键时将其作为一种数据类型使用,但在调用msgbox(variant)时它默认为另一种数据类型,因此它不会显示,因为即使文本相同,数据类型也不同?因此,使用temp是一种无意的桥梁,无意中将其作为不同的数据类型保存在字典中,而msgbox默认为?@grandrilly-No的数据类型恰好是相同的类型(
Range
)。您不能
MsgBox
对象,因此它调用其默认成员-
.Value
。分配给
temp
做了完全相同的事情,因为您没有在它前面使用
Set
。没有
Set
关键字的
Variant
的赋值是值赋值,而不是引用赋值。我想我现在更糊涂了<代码>单元格(1,1)
是范围对象。temp是一个(n个未声明的)变量,因此它隐式地将自身设置为等于
单元格(1,1).Value
。而range是一个对象(?),因此msgbox试图通过添加
.value
,生成
单元格(1,1).value
,来解决这个问题。我的意思是,显然不是这样,否则它会起作用,因为这是相同的结果,但是…@Grabundry-这几乎就是发生的事情。从技术上讲,它调用
单元格(1,1)。[\u默认值]
,但这与
单元格(1,1)是一样的。这(不是我的)可能有助于澄清工作中的概念。
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