在前两期,我们主要采用“结构体(Type)+ 函数”的方式来构建复杂的数据模型。这种方式的优点在于结构清晰、逻辑明确,便于理解和上手。然而,它也存在一些不足:数据与行为仅实现了初步解耦,数据扩展性有限,且在处理数组等集合数据时效率不高
为了平衡性能以及可扩展性,又要如何改变呢?
原有模式的局限性
关于原有模式“结构体+函数+数组”的局限性,还是以图书馆里的“图书”为例加以说明
1.1 扩展性
刚开始,我们通过结构体定义了“图书”结构如下:
' 自定义数据类型:图书Public Type BookTitle As String ' 属性:书名Author As String ' 属性:作者ISBN As String ' 属性:ISBN号Status As Integer ' 属性:状态 (使用上面的常量)PageCount As Integer ' 属性:页数End Type
后来在使用中发现还需要增加一个必要的属性,如图书的语言,那么,接下来我们要级联修改的内容如下:
修改 Type Book 的定义 → 添加 Language As String
修改所有创建 Book 实例的地方(初始化代码)
修改所有读取 Book.Language 的代码(如显示图书信息函数、“图书”与“读者”交互的函数)
总之一句话,只要增加一个“语言”属性,所有使用该Type的代码都可能受到影响,引发大规模代码改动,兼容性差
1.2 性能
主要体现在使用数组管理“图书”上,假设图书馆里有10000本书,我们从增、删、查三个方面详细说明:
“图书”查询:这是一个 O(N) 的线性查找。为了找一本书,它必须从数组的第一个元素开始,逐个比较ISBN或书名,直到找到目标或遍历完整个数组。在最坏的情况下(找最后一本书或找不到的书),需要进行 10,000 次比较。平均下来需要 5,000 次比较。如果再遇到频繁借阅、归还、查询操作时,这种延迟会累积得非常明显,导致程序卡顿
增加“图书”:在末尾追加很快,但如果需要按ISBN排序插入,或者数组已满需要 ReDim Preserve,则效率会很低。ReDim Preserve 会创建一个新的、更大的数组,并将旧数组的所有数据复制过去,这是一个 O(N) 的操作,这会非常慢
删除“图书”:当删除中间的一本书后,为了保持连续性,需要将后面所有的书向前移动填补空缺。这也是一个 O(N) 的操作
改进方案
仅从性能和可扩展方面来看,更推荐使用数据字典,对的,你没有看错,是数据字典Dictionary
用数据字典来管理“图书”,本质上就是用空间换时间,并借助其精妙的数据结构,把一个需要线性扫描的笨拙过程,变成了一个可以随机瞬间访问的智能过程。从而把我们从繁琐的底层循环和数据搬运中解放出来,专注于业务本身
示例代码:
Dim Library As Object' 初始化字典Sub InitLibrary()Set Library = CreateObject("Scripting.Dictionary")' 设置比较模式,例如不区分大小写Library.CompareMode = vbTextCompareEnd Sub' 添加图书Sub AddBookToDict(title As String, author As String, isbn As String, status As String, pageCount As Long, language As String)If Not Library.Exists(isbn) ThenDim bookDetail As ObjectSet bookDetail = CreateObject("Scripting.Dictionary")bookDetail("Title") = titlebookDetail("Author") = authorbookDetail("Status") = statusbookDetail("PageCount") = pageCountbookDetail("Language") = languageLibrary.Add isbn, bookDetailElseMsgBox "ISBN已存在!"End IfEnd Sub
通过采用数据字典,不仅提升了数据处理效率,还增强了系统的可维护性与扩展性,是一种务实、高效且在实际应用中被验证为成功的实践路径
结束语
以上代码中关于字典Dictionary的应用是不是颠覆了大家的认知呢?从最基础的层面看,一个Dictionary对象由成对的 Key 和 Item 组成,为何代码中可以添加许多个字段呢?哪个字段是key哪个又是Item?你有没有类似的困惑?别急,咱们下期继续讨论
公众号同时也在不间断地分享免费的编程案例,如果想学习更多的编程知识,无论是用来提升自动化办公效率还是想提升自我,都可以关注我的公众号“努力鸭是黑色的”,解锁更多的VBA技能