Dictionary.Exists 为变量键和常量键返回不同的值

Dictionary.Exists Returning Different Values for Variable and Constant Key

我一直在使用 MS Scripting Runtime Library 字典作为我目前正在处理的 VBA 项目的 goto 数据结构,但我只是 运行 遇到了一个令人沮丧的问题我认为他们可能真的没有我想象的那么好。 .Exists 方法似乎是一个非常有用的方法,但是当我尝试在 For 循环中使用它时,我得到了一些奇怪的行为:

Sub TestExists()
Dim i As Long
Dim dRowsInEachCol As Dictionary
Set dRowsInEachCol = New Dictionary

Dim lColLen As Long, lColLenFreq As Long

For i = 0 To 100
    dRowsInEachCol.Add i, i
Next

Dim dColLenFreqs As Dictionary
For i = 0 To dRowsInEachCol.Count - 1
        
    lColLen = dRowsInEachCol.Items()(i)
    
    If i = 0 Then
        Set dColLenFreqs = New Dictionary
    End If
    Debug.Print dColLenFreqs.Exists(0), _
                dColLenFreqs.Exists(1), _
                dColLenFreqs.Exists(lColLen)
                
    If dColLenFreqs.Exists(lColLen) Then
         lColLenFreq = dColLenFreqs.Item(lColLen) + 1
    Else
        lColLenFreq = 1
    End If
    
'        'This will add a new item to dUniqColLengths _
'            w/ key = column length, or overwrite item w/ _
'            new column number if that key exists already _
'            (INTENDED result is unique col lengths only in dict):
    dColLenFreqs.Item(lColLen) = lColLenFreq
Next
End Sub

首先,当我创建字典时,似乎有一个没有项目的键被隐式添加(similar to the issue in this question)。但是我不能接受这个问题的本质并解决它,因为当我检查 lColLen 与具有与 lColLen 相同值的常量时,我​​实际上得到了 Exists 方法的不同结果.这是执行行 Set dColLenFreqs = New Dictionary 后手表 window 的状态:

我已经尝试切换到后期绑定并完全限定我的字典变量声明,但这并没有解决问题。

如果相关,函数的目的是获取字典输入(dRowsInEachCol 是预期的输入,但我修改为在函数内创建字典以消除此问题并缩短代码),和 return 一个字典,其中 dRowsInEachCol 中的唯一项作为键,dRowsInEachCol 中每个唯一项的频率作为项。

我想知道:

  1. 这只是 Scripting.Dictionary 对象中的错误,还是我遗漏了什么?
  2. 如果它是 Scripting.Dictionary 对象中的错误,有哪些解决方法可用?我读过 mac-compatible dictionary classes like this one and this one,但我担心这些会导致其他故障。这些恐惧是有根据的吗?另一个想法是只切换到临时 excel 运行ges 或集合和数组,可能包含在 class 中。我也愿意接受其他建议。

This previous question好像也和我的问题有点关系,或许可以参考。

编辑重复: 由于 ,这被标记为重复,阅读 Tim Williams 的回答后,我明白了为什么这些问题是相关的,尽管另一个问题有所不同,因为它假定 Tim Williams 的答案,然后问为什么。我真的没有什么可以添加到我的问题来进一步区分它,我同意对另一个问题有一个 link 是有帮助的,但是如果有人遇到与我相同的问题并且没有意识到它是由手表引起的 window,他们将更有可能在搜索结果中找到这个问题。

无法在此处复制 - 在第一次通过循环时,所有三个 Exists 监视值都是假的。

不过你还设置了哪些手表?有可能另一个手表正在改变 Exists 结果:在使用 Dictionary 对象时需要小心手表 window。

例如见:

编辑:正如所怀疑的那样,在

上添加手表后
dColLenFreqs.Item(lColLen) 

手表

dColLenFreqs.Exists(lColLen) 

现在输出 True。

如果您删除所有手表并只查看调试输出,您也会看到它如预期的那样。