VBA for循环添加空白字典条目

时间:2019-04-05 03:57:27

标签: excel vba dictionary for-loop

我正在尝试使用VBA词典替换Excel工作表中的某些值。 去年当我这样做时,它运行良好。再次尝试后,它会将空白值添加到重复键中,因此没有将任何内容写入单元格。

我尝试过早期绑定和后期绑定都没有成功。

这是绑定较晚的代码。

Sub someDict()

Dim myDict As Object
Set myDict = CreateObject("Scripting.Dictionary")
Dim n As Long
Dim i As Long

myDict.Add "A", "Amaretto Sour"
myDict.Add "B", "Bourbon"
myDict.Add "C", "Cosmopolitan"
myDict.Add "D", "Daiquiri"
myDict.Add "E", "Electric Lemonade"
myDict.Add "F", "Four Horsemen"
myDict.Add "G", "Gin and Tonic"
myDict.Add "H", "Hurricane"
myDict.Add "I", "Irish Coffee"
myDict.Add "J", "John Collins"

Debug.Print "Total: " & myDict.Count()

n = Cells(Rows.Count, 1).End(xlUp).Row
For i = n To 1 Step -1
    If Cells(i, 3) = "TEST" Then
        Debug.Print myDict.Count()
        Cells(i, 5) = myDict(Cells(i, 4))
        Debug.Print myDict.Count()
    End If
Next i

Debug.Print "Total after loop: " & myDict.Count()

Dim k As Variant
For Each k In myDict.Keys
    ' Print key and value
    Debug.Print k, myDict(k)
Next

End Sub

这是表结构:

table

立即数的当前输出为:

Total: 10
 10 
 11 
 11 
 12 
 12 
 13 
 13 
 14 
 14 
 15 
 15 
 16 
 16 
 17 
Total after loop: 17
A             Amaretto Sour
B             Bourbon
C             Cosmopolitan
D             Daiquiri
E             Electric Lemonade
F             Four Horsemen
G             Gin and Tonic
H             Hurricane
I             Irish Coffee
J             John Collins
J             
H             
G             
F             
E             
C             
A     

我希望它是:

Total: 10
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
 10 
Total after loop: 10
A             Amaretto Sour
B             Bourbon
C             Cosmopolitan
D             Daiquiri
E             Electric Lemonade
F             Four Horsemen
G             Gin and Tonic
H             Hurricane
I             Irish Coffee
J             John Collins

任何人都可以告诉我我做错了什么(除了使用VBA词典),此外,为什么它以前对我有用?

可能是由于更新了scrobj.dll吗?

谢谢。

1 个答案:

答案 0 :(得分:1)

词典实际上使用键的变体,而不是严格使用字符串或数字,这就是为什么在循环键时必须将k定义为变体的原因。钥匙实际上可以是任何东西。

此外,如果引用未定义的键,则字典会自发添加新键,这就是为什么必须使用安全功能Exists来测试是否已定义键的原因。

VBA本身就是不受约束的野兽,当您在代码中引用Range()对象时,它会试图帮助您确定所需的内容。如果可以使用范围对象,则它将使用范围对象。如果需要一个字符串/数字,则它将使用Range()对象的值代替(作为默认属性)。

因为字典可以将任何对象用作键,而不是使用Cells(i,4)中的值,所以它使用Cells(i,4)的实际范围对象并创建一个没有值的新键。您可以在“本地”窗口中看到此信息,该窗口显示了变体词典键的子类型:

enter image description here

在最后调试.print键时,打印功能需要一个字符串/数字。因此,当到达实际上是范围对象的“重复”键时,它将打印范围对象的值。

单步执行代码时,实际上您可以在即时窗口中获得这些键的任何范围属性!例如:?k.Address

要修复您的代码,您只需要显式引用单元格的值即可:

    Cells(i, 5) = myDict(Cells(i, 4).Value)

这就是为什么最佳编码实践是始终显式引用对象的属性,而不是依赖默认属性的原因。