在我的VBA程序中,我有一本词典
Dim dic As Variant
Set dic = CreateObject("Scripting.Dictionary")
我正在添加一堆字符串项(假设为100),其中一些具有值""
示例:
Key | Value
-------------------
"A" | 1
"B" | ""
"C" | 3
"D" | 4
"E" | ""
etc.
我知道有一种方法可以使用dic.Count("A")
来计算密钥出现次数,但我想计算一下我的字典中有多少项具有值""
(在我的示例中为2)而没有循环通过每个项目。
我尝试了以下但没有成功:
MsgBox "dic.item()count=" & dic.Item("").Count
MsgBox "dic.item()count=" & dic("").Count
如何实现这一目标?有没有类似dic.Value("").Count
的方法?
答案 0 :(得分:4)
这很难看,但它不是循环:
事实证明,即使是超大字典,这种方法也能很快地运行。
'Convert the Dictionary to an Array
MyArray = dic.Items
'Convert the Array to a String
MyString = Join(MyArray, ";")
'Blank Items in the Dictionary will result in ";;" appearing in the String
'Split the String on ;;
MyArray = Split(MyString, ";;", -1, vbTextCompare)
'A String with no ";;"'s will result in a 1 element array
'A String with 2 occurances of ;; will give a 3 element array
NumberOfBlankItems = UBound(MyArray)
进行了一些编辑来修复一些小的逻辑错误(Split是错误的参数数量,因为它是一个基于零的数组,所以不需要减去1)
另外,我使用20,000元素字典进行测试,并且在循环字典与此方法之间没有明显的速度差异。也许它不像我想象的那么难看......
我使用此代码再做了一次测试:
Sub DictionaryTest()
Dim dic As New Dictionary 'Variant
Dim r As Long
Dim key As Variant
Dim myArray As Variant
Dim mystring As String
Dim NumberOfBlankItems As Integer
Set dic = CreateObject("Scripting.Dictionary")
For r = 1 To 500000
dic.Add "Key " & r, CInt(Int((600 * Rnd()) + 1))
Next
r = 0
Debug.Print "Starting count by looping: " & Now()
For Each key In dic
If dic.item(key) = 300 Then r = r + 1
Next
Debug.Print "Count by looping: " & r
Debug.Print "Starting count by splitting: " & Now()
myArray = dic.Items
mystring = Join(myArray, ";")
myArray = Split(mystring, "300;", -1, vbTextCompare)
NumberOfBlankItems = UBound(myArray)
Debug.Print "Count by splitting: " & NumberOfBlankItems
Debug.Print "Finish time: " & Now()
End Sub
立即窗口:
Starting count by looping: 6/15/2016 3:02:47 PM
Count by looping: 818
Starting count by splitting: 6/15/2016 3:03:16 PM
Count by splitting: 818
Finish time: 6/15/2016 3:03:16 PM
正如你所看到的,即使字典中有500,000个条目,分割字符串所花费的时间(一个字符串几乎不超过20亿个字符!)仍然只有大约1秒!