RPA 见解

在 Excel VBA 中使用 Dictionary

2019-03-10  本文已影响25人  Creator_蔚蓝

需求 让 VBA 程序的配置数据放置在程序外面,使数据与逻辑分离

这样带来的好处就是可以通过修改配置而不需要修改代码来改变程序的行为。使 Excel VBA 程序的可维护性更好,让不会 VBA 程序的人也可以个性化程序的行为。

在 Excel VBA 中可以使用字典存储一些配置数据,参照机器人框架,让 Excel 程序也做到数据与逻辑分离。

Step 1 添加引用 Microsoft Scripting Runtime

要想使用 Excel VBA 的 Dictionary ,你必须先引用 Microsoft Scripting Runtime

Step 2 在程序中 New 一个 Dictionary 对象

Option Explicit

Public Sub DicTest()
    'Step 2 Create a dictionary object
    Dim dic As New Dictionary
    
End Sub

Step 3 像其它的编程语言( 如 C# )一样为字典添加键/值(Key / Value)对


Option Explicit

Public Sub DicTest()
    'Step 2 Create a dictionary object
    Dim dic As New Dictionary
    
    'Step 3 Add key and value to the dictionary object
    Call dic.Add("Key1", "this is the value of Key1")
    
End Sub

Step 4 你可以通过字典的 Item() 方法通过 Key 来获取对应的 Value

Option Explicit

Public Sub DicTest()
    'Step 2 Create a dictionary object
    Dim dic As New Dictionary
    
    'Step 3 Add key and value to the dictionary object
    Call dic.Add("Key1", "this is the value of Key1")
    
    
    'Step 4 Using the method Item() to get the vaue by the key
    Debug.Print dic.Item("Key1")
    
End Sub

毫无意外的,运行上述程序,在 Immediate 窗口中输出如下结果:

这着意味着我们可以像 REFFramework 一样,将所有的配置信息集中存储在一个 Config 文件中,在程序初始化阶段,将所有的配置数据读取到字典中,并在 Excel VBA 程序中传递这个字典,在需要的地方根据配置的 Key 来读取配置值。

哈哈,REFFramework 其实也可以指导我们更好地编写 VBA 程序。

其它

Q1:如果读取一个不存在的 key 会怎样?
A:程序并不会报错,会返回一个空的字符串

Q2: 如果添加了重复的 Key 会怎样?
A:会返回一个错误

Q3: 怎么避免 Add 重复 Key 的错误?
A:Add Key 之前先判断一下 Key 是否已经存在,如果存在,则不再添加或者覆盖,如果不存在则 Add 一个新的键值对。具体实现思路如下:

 'Add the keys and values to the dic
    With rngConfig
        '# The settings should starts form row 2
        For rowNum = 2 To .Rows.Count Step 1
            'If the key is not empty, add it to the dictionay
            If .Cells(rowNum, 1).Value <> "" Then
                If dicConfig.Exists(.Cells(rowNum, 1).Value) Then
                    'If the key exits,overwrite the key
                    dicConfig.Item(.Cells(rowNum, 1).Value) = _
                                   .Cells(rowNum, 2).Value
                Else
                    'If the key not exits, add a new pair of key
                    Call dicConfig.Add(.Cells(rowNum, 1).Value, _
                                       .Cells(rowNum, 2).Value)
                End If
            End If
        Next rowNum
    End With

Q4: 怎么遍历 dictionary ?
A:你不能通过 For each key in Dictionary.Keys 之类的语法来遍历 dictionary,因为你不能创建 key 对象,(Key 只是 Dictionary 的属性值,你没有什么办法可以创建它)

通过对象浏览器,你可以看到 dictionary 有一个 Count 属性表示 Keys 的总数,Keys 属性代表一个数组

对象浏览器

我们可以尝试通过递增的索引一个个 key 读出来然后根据 key 用 item 方法把 Value 读出来,像这样:

     Dim KeyIndex As Integer
    For KeyIndex = 0 To (dicConfig.Count - 1) Step 1
        Debug.Print dicConfig.Keys(KeyIndex) & "|" & _
                    dicConfig.Item(dicConfig.Keys(KeyIndex))
    Next KeyIndex

注意: dictionary 对象的 Index 并不像 VBA 的数组那样以 1 开始,而是以 0 开始。

我的 config.xlsx 是这样的:

config.xlsx

最终输出的结果如下:


一切都像我们预料的那样运行!

Q5: Dictionary 对象还有哪些属性和方法?
A: 其实你可以通过 VBE 自带的对象浏览器查看。Dictionary 对象的方法和属性其实不多,但是麻雀虽小,五脏俱全。它拥有字典对象应该有的一切。只要你使用得合理,字典得特性一样都不会少。

上一篇下一篇

猜你喜欢

热点阅读