Dictionary.Exists为变量和常量键

时间:2018-02-21 00:25:33

标签: vba excel-vba dictionary watch excel

我一直在使用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行之后的观察窗口的状态: How could this watch window be possible ever?

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

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

我想知道:

  1. 这只是Scripting.Dictionary对象中的一个错误,还是我错过了什么?
  2. 如果是Scripting.Dictionary对象中的错误,可以使用哪些变通方法?我已经阅读了与mac兼容的字典类like this onethis one,但我担心这些会导致其他故障。这些恐惧是否成立?另一个想法是只需切换到临时excel范围或集合和数组,可能包含在类中。我也对其他建议持开放态度。
  3. This previous question似乎与我的问题有些相关,可能对参考有用。

    不重要的编辑:由于this question,这被标记为重复,在阅读了Tim Williams的答案之后,我可以看到为什么这些问题是相关的,尽管另一个问题是不同的因为它假定蒂姆威廉姆斯的答案,然后问为什么。我没有任何东西可以添加到我的问题中以进一步区分它,我同意链接到另一个问题是有帮助的,所以我会留给社区来决定它是否应该被关闭作为重复

1 个答案:

答案 0 :(得分:1)

不能在这里复制 - 在第一次通过循环时,所有三个Exists监视值都是false。

你准备了哪些其他手表?可能另一只手表正在改变Exists结果:使用Dictionary对象时需要注意观察窗口。

E.g。见:

Dictionary is populated with an empty item after checking dictionary item in watch window

编辑:怀疑,在

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

上的手表

dColLenFreqs.Exists(lColLen) 

现在输出True。

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