Answers:
是。
设置对MS脚本运行时的引用(“ Microsoft脚本运行时”)。按照@regjo的注释,转到“工具”->“参考”,然后选中“ Microsoft脚本运行时”框。
使用以下代码创建字典实例:
Set dict = CreateObject("Scripting.Dictionary")
要么
Dim dict As New Scripting.Dictionary
使用示例:
If Not dict.Exists(key) Then
dict.Add key, value
End If
Nothing
使用完字典后,请不要忘记将其设置为。
Set dict = Nothing
keyed
。
Dim dict As New Scripting.Dictionary
。如果没有引用,则必须使用CreateObject
实例化此对象的后期绑定方法。
VBA具有收集对象:
Dim c As Collection
Set c = New Collection
c.Add "Data1", "Key1"
c.Add "Data2", "Key2"
c.Add "Data3", "Key3"
'Insert data via key into cell A1
Range("A1").Value = c.Item("Key2")
该Collection
对象使用哈希执行基于键的查找,因此速度很快。
您可以使用Contains()
函数来检查特定集合是否包含键:
Public Function Contains(col As Collection, key As Variant) As Boolean
On Error Resume Next
col(key) ' Just try it. If it fails, Err.Number will be nonzero.
Contains = (Err.Number = 0)
Err.Clear
End Function
编辑2015年6月24日:Contains()
感谢@TWiStErRob。
编辑2015年9月25日:Err.Clear()
感谢@scipilot。
ContainsKey
; 仅阅读该调用的人可能会混淆它以检查它是否包含特定值。
另一个字典示例,对于包含发生频率很有用。
循环外:
Dim dict As New Scripting.dictionary
Dim MyVar as String
循环内:
'dictionary
If dict.Exists(MyVar) Then
dict.Item(MyVar) = dict.Item(MyVar) + 1 'increment
Else
dict.Item(MyVar) = 1 'set as 1st occurence
End If
要检查频率:
Dim i As Integer
For i = 0 To dict.Count - 1 ' lower index 0 (instead of 1)
Debug.Print dict.Items(i) & " " & dict.Keys(i)
Next i
建立cjrh的答案,我们可以构建一个不需要标签的Contains函数(我不喜欢使用标签)。
Public Function Contains(Col As Collection, Key As String) As Boolean
Contains = True
On Error Resume Next
err.Clear
Col (Key)
If err.Number <> 0 Then
Contains = False
err.Clear
End If
On Error GoTo 0
End Function
对于我的一个项目,我编写了一组辅助函数来使Collection
行为更像Dictionary
。它仍然允许递归集合。您会注意到Key始终是第一位的,因为它是强制性的,在我的实现中更有意义。我也只使用了String
键。您可以根据需要将其更改回去。
我将其重命名为set,因为它将覆盖旧值。
Private Sub cSet(ByRef Col As Collection, Key As String, Item As Variant)
If (cHas(Col, Key)) Then Col.Remove Key
Col.Add Array(Key, Item), Key
End Sub
这些err
东西是用于对象的,因为您将使用set
和而不使用对象来传递对象。我认为您可以检查它是否是一个对象,但是我被迫等待时间。
Private Function cGet(ByRef Col As Collection, Key As String) As Variant
If Not cHas(Col, Key) Then Exit Function
On Error Resume Next
err.Clear
Set cGet = Col(Key)(1)
If err.Number = 13 Then
err.Clear
cGet = Col(Key)(1)
End If
On Error GoTo 0
If err.Number <> 0 Then Call err.raise(err.Number, err.Source, err.Description, err.HelpFile, err.HelpContext)
End Function
这篇文章的原因...
Public Function cHas(Col As Collection, Key As String) As Boolean
cHas = True
On Error Resume Next
err.Clear
Col (Key)
If err.Number <> 0 Then
cHas = False
err.Clear
End If
On Error GoTo 0
End Function
如果不存在,则不抛出。只要确保将其删除即可。
Private Sub cRemove(ByRef Col As Collection, Key As String)
If cHas(Col, Key) Then Col.Remove Key
End Sub
获取一个键数组。
Private Function cKeys(ByRef Col As Collection) As String()
Dim Initialized As Boolean
Dim Keys() As String
For Each Item In Col
If Not Initialized Then
ReDim Preserve Keys(0)
Keys(UBound(Keys)) = Item(0)
Initialized = True
Else
ReDim Preserve Keys(UBound(Keys) + 1)
Keys(UBound(Keys)) = Item(0)
End If
Next Item
cKeys = Keys
End Function
如果由于某种原因您不能或不想将其他功能安装到Excel中,则也可以使用数组,至少对于简单的问题而言。作为WhatIsCapital,您输入国家的名称,该函数返回您的资本。
Sub arrays()
Dim WhatIsCapital As String, Country As Array, Capital As Array, Answer As String
WhatIsCapital = "Sweden"
Country = Array("UK", "Sweden", "Germany", "France")
Capital = Array("London", "Stockholm", "Berlin", "Paris")
For i = 0 To 10
If WhatIsCapital = Country(i) Then Answer = Capital(i)
Next i
Debug.Print Answer
End Sub
Dim
的关键字,Country
并且Capital
需要被声明为变体由于使用的Array()
,i
应当声明(而且必须是,如果Option Explicit
是一套),以及循环计数器会抛出一个出界错误的-更安全使用UBound(Country)
的To
价值。还可能值得注意的是,虽然该Array()
函数是有用的快捷方式,但它不是在VBA中声明数组的标准方法。
所有其他人都已经提到使用Dictionary类的scripting.runtime版本。如果无法使用此DLL,则也可以使用此版本,只需将其添加到代码中即可。
https://github.com/VBA-tools/VBA-Dictionary/blob/master/Dictionary.cls
它与Microsoft的版本相同。