VBA常见字典用法集锦及代码详解 vba字典的使用
bigegpt 2024-12-25 10:23 17 浏览
在VBA(Visual Basic for Applications)中,字典(Dictionary)是一种非常实用的对象,它允许我们存储键值对(Key-Value pairs),其中键(Key)是唯一的,而值(Value)可以是任何数据类型。字典在数据处理、数据去重、数据匹配等方面有着广泛的应用。本文将介绍VBA中字典的常见用法,并通过代码示例进行详细解析。
字典(dictionary)是一个储存数据的小仓库。共有两列,第一列叫key , 不允许有重复的元素。第二列是item,每一个key对应一个item,本列允许为重复。如下表所示。
key | item(s) |
B | B1 |
a | a1 |
b | b1 |
B | B1 |
既然有数组,为什么还要学字典?
在VBA中,虽然数组是一个非常强大且基础的数据结构,用于存储和操作一系列相同类型的数据,但在处理复杂数据时,字典(Dictionary)提供了额外的灵活性和效率,这是数组难以直接提供的。以下是几个关键原因:
?键值对存储?:字典以键值对(Key-Value Pair)的形式存储数据,每个键都是唯一的,与之关联的值可以是任何类型的数据。这种存储方式使得数据检索变得非常快速和直接,因为你可以直接通过键来访问对应的值,而不需要像数组那样通过索引来遍历。
?动态集合?:与数组相比,字典是动态的。在VBA中,数组的大小一旦在声明时确定(除非使用动态数组并重新分配),就不能轻易改变。而字典则可以在运行时动态地添加、删除或修改键值对,无需担心数据容量的限制。
?易于管理和维护?:在处理大量相关数据时,字典提供了更清晰的数据结构。每个键都代表了一个特定的标识符或分类,使得数据的管理和维护变得更加直观和方便。
?避免数据重复?:由于字典的键是唯一的,这有助于避免在数据集中存储重复的值。当你尝试添加一个已存在的键时,字典会覆盖与该键关联的旧值,或者你可以选择不执行任何操作,具体取决于你的需求。
?性能优化?:在处理大量数据时,字典的查找速度通常比遍历数组要快得多。这是因为字典内部使用了哈希表等高效的数据结构来存储键值对,使得查找操作的时间复杂度接近O(1)。
?高级功能?:一些字典实现(如VBA中的Scripting.Dictionary)还提供了额外的功能,如Exists方法来检查某个键是否存在于字典中,以及Keys和Items集合来分别获取字典中所有的键和值。
虽然数组是VBA中不可或缺的数据结构,但在处理复杂数据时,字典提供了更高的灵活性和效率。因此,学习如何在VBA中使用字典是非常有价值的。
字典有什么局限?
字典只有两列,如果要处理多列的数据,还需要通过字符串的组合和拆分来实现。字典调用会耗费一定时间,如果是数据量不大,字典的优势就无法体现出来。
字典在哪里?如何创建字典?
在VBA中,创建字典对象通常有两种方式:前期绑定和后期绑定。前期绑定需要在VBA编辑器中引用“Microsoft Scripting Runtime”库,而后期绑定则不需要,但相对来说,后期绑定的代码兼容性更好。
前期绑定:
Dim dict As Dictionary
Set dict = New Dictionary
后期绑定:
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
添加键值对
Dim dict As Object
Set dict = CreateObject("Scripting.Dictionary")
获取值
通过键名来获取对应的值。
Dim value As Variant
value = dict("key1")
删除键值对
使用Remove方法删除字典中的键值对。
dict.Remove "key1"
遍历字典
遍历字典可以通过For Each循环和Keys或Items方法实现。
Dim key As Variant
Dim item As Variant
For Each key In dict.Keys
item = dict(key)
' 在此处处理每个键值对
Next key
例1.字典去重
Sub 字典去重() '去重
Dim ws As Worksheet
Dim lastRow,i As Long
Dim dict As Object
Dim uniqueValues As Range
Set dict = CreateObject("Scripting.Dictionary")
Set ws = ThisWorkbook.Sheets("Sheet1") ' 修改为你的工作表名称
lastRow = ws.Cells(ws.Rows.Count, "A").End(xlUp).Row ' 假设数据在A列
' 遍历A列,将数据添加到字典中
For i = 1 To lastRow
If Not dict.Exists(ws.Cells(i, 1).Value) Then
dict.Add ws.Cells(i, 1).Value, Nothing ' 这里的Value可以是任何值,因为我们只关心Key的唯一性
End If
Next i
' 创建一个新的范围来存放去重后的数据
Set uniqueValues = ws.Range("B1").Resize(dict.Count, 1)
' 将去重后的数据写入新的范围
Dim key As Variant
i = 1
For Each key In dict.Keys
uniqueValues.Cells(i, 1).Value = key
i = i + 1
Next key
End Sub
代码说明:
?这个例子假设你的数据在Sheet1的A列中。代码遍历A列的每个单元格,将其值作为键添加到字典中。如果键已存在,则不执行任何操作(因为字典不允许重复的键)。去重后的数据被写入到B列,从B1开始。
例2.如何在VBA中使用Scripting.Dictionary对象来存储键值对。
第一列的值作为键(Key),第二列的值作为项(Item),并处理可能出现的重复键错误,最后将所有键和值的信息显示在一个消息框中。代码如下:
Sub t1Optimized()
' 声明一个变量D作为Object类型,用于创建Scripting.Dictionary对象
Dim D As Object
' 使用CreateObject函数创建一个Scripting.Dictionary对象实例
Set D = CreateObject("Scripting.Dictionary")
' 声明循环变量x和key变量,以及用于存储最终输出的字符串变量output
Dim x As Integer
Dim key As Variant
Dim output As String
' 启用错误处理,如果在添加键时发生错误(如键已存在),则忽略错误
On Error Resume Next
' 循环遍历第2行到第5行的数据,将第一列的值作为键,第二列的值作为项添加到字典D中
For x = 2 To 5
D.Add Cells(x, 1).Value, Cells(x, 2).Value
' 检查是否有错误发生(如尝试添加已存在的键)
If Err.Number <> 0 Then
' 如果有错误,清除错误状态,以便继续执行循环
Err.Clear ' 清除错误
End If
Next x
' 关闭错误处理,让之后的错误能够正常抛出
On Error GoTo 0
' 初始化输出字符串,添加标题信息
output = "Keys and Items:" & vbCrLf
' 遍历字典D中的所有键
For Each key In D.Keys
' 将每个键和对应的项添加到输出字符串中,每个键值对后添加换行符
output = output & "Key: " & key & ", Item: " & D(key) & vbCrLf
Next key
' 使用MsgBox函数显示包含所有键和项信息的字符串
MsgBox output
End Sub
例3.运用字典实现按库位和名称汇总数量
Sub 字典求和()
' 声明变量
Dim arr, D As Object, ar
Dim i As Integer, j As Byte
' 创建字典对象
Set D = CreateObject("Scripting.Dictionary")
' 将选定区域的数据装入数组
arr = Sheet3.Range("a1").CurrentRegion
' 循环处理数据
For i = 1 To UBound(arr)
' 将日期和名称拼接成键值
Dim t As String
t = arr(i, 1) & "|" & arr(i, 2)
' 判断键值是否存在于字典中
If D.Exists(t) Then
' 如果存在,则更新对应销售额
D(t) = t & "|" & (Val(Split(D(t), "|")(2)) + arr(i, 3))
Else
' 如果不存在,存入"日期|名称|销售额"
D(t) = t & "|" & arr(i, 3)
End If
Next i
' 清除原数组数据
Erase arr
' 重新调整数组大小
ReDim arr(1 To D.Count, 1 To 3)
' 获取字典中的值部分
ar = D.Items
' 将数据填充至新数组
For i = 1 To UBound(ar) + 1
For j = 1 To 3
arr(i, j) = Split(ar(i - 1), "|")(j - 1)
Next j
Next i
' 清除 Sheet4 中的内容
Sheet4.Range("a1").CurrentRegion.ClearContents
' 将处理后的数据输出到 Sheet4
Sheet4.Range("a1").Resize(UBound(arr), 3) = arr
End Sub
相关推荐
- 得物可观测平台架构升级:基于GreptimeDB的全新监控体系实践
-
一、摘要在前端可观测分析场景中,需要实时观测并处理多地、多环境的运行情况,以保障Web应用和移动端的可用性与性能。传统方案往往依赖代理Agent→消息队列→流计算引擎→OLAP存储...
- warm-flow新春版:网关直连和流程图重构
-
本期主要解决了网关直连和流程图重构,可以自此之后可支持各种复杂的网关混合、多网关直连使用。-新增Ruoyi-Vue-Plus优秀开源集成案例更新日志[feat]导入、导出和保存等新增json格式支持...
- 扣子空间体验报告
-
在数字化时代,智能工具的应用正不断拓展到我们工作和生活的各个角落。从任务规划到项目执行,再到任务管理,作者深入探讨了这款工具在不同场景下的表现和潜力。通过具体的应用实例,文章展示了扣子空间如何帮助用户...
- spider-flow:开源的可视化方式定义爬虫方案
-
spider-flow简介spider-flow是一个爬虫平台,以可视化推拽方式定义爬取流程,无需代码即可实现一个爬虫服务。spider-flow特性支持css选择器、正则提取支持JSON/XML格式...
- solon-flow 你好世界!
-
solon-flow是一个基础级的流处理引擎(可用于业务规则、决策处理、计算编排、流程审批等......)。提供有“开放式”驱动定制支持,像jdbc有mysql或pgsql等驱动,可...
- 新一代开源爬虫平台:SpiderFlow
-
SpiderFlow:新一代爬虫平台,以图形化方式定义爬虫流程,不写代码即可完成爬虫。-精选真开源,释放新价值。概览Spider-Flow是一个开源的、面向所有用户的Web端爬虫构建平台,它使用Ja...
- 通过 SQL 训练机器学习模型的引擎
-
关注薪资待遇的同学应该知道,机器学习相关的岗位工资普遍偏高啊。同时随着各种通用机器学习框架的出现,机器学习的门槛也在逐渐降低,训练一个简单的机器学习模型变得不那么难。但是不得不承认对于一些数据相关的工...
- 鼠须管输入法rime for Mac
-
鼠须管输入法forMac是一款十分新颖的跨平台输入法软件,全名是中州韵输入法引擎,鼠须管输入法mac版不仅仅是一个输入法,而是一个输入法算法框架。Rime的基础架构十分精良,一套算法支持了拼音、...
- Go语言 1.20 版本正式发布:新版详细介绍
-
Go1.20简介最新的Go版本1.20在Go1.19发布六个月后发布。它的大部分更改都在工具链、运行时和库的实现中。一如既往,该版本保持了Go1的兼容性承诺。我们期望几乎所...
- iOS 10平台SpriteKit新特性之Tile Maps(上)
-
简介苹果公司在WWDC2016大会上向人们展示了一大批新的好东西。其中之一就是SpriteKitTileEditor。这款工具易于上手,而且看起来速度特别快。在本教程中,你将了解关于TileE...
- 程序员简历例句—范例Java、Python、C++模板
-
个人简介通用简介:有良好的代码风格,通过添加注释提高代码可读性,注重代码质量,研读过XXX,XXX等多个开源项目源码从而学习增强代码的健壮性与扩展性。具备良好的代码编程习惯及文档编写能力,参与多个高...
- Telerik UI for iOS Q3 2015正式发布
-
近日,TelerikUIforiOS正式发布了Q32015。新版本新增对XCode7、Swift2.0和iOS9的支持,同时还新增了对数轴、不连续的日期时间轴等;改进TKDataPoin...
- ios使用ijkplayer+nginx进行视频直播
-
上两节,我们讲到使用nginx和ngixn的rtmp模块搭建直播的服务器,接着我们讲解了在Android使用ijkplayer来作为我们的视频直播播放器,整个过程中,需要注意的就是ijlplayer编...
- IOS技术分享|iOS快速生成开发文档(一)
-
前言对于开发人员而言,文档的作用不言而喻。文档不仅可以提高软件开发效率,还能便于以后的软件开发、使用和维护。本文主要讲述Objective-C快速生成开发文档工具appledoc。简介apple...
- macOS下配置VS Code C++开发环境
-
本文介绍在苹果macOS操作系统下,配置VisualStudioCode的C/C++开发环境的过程,本环境使用Clang/LLVM编译器和调试器。一、前置条件本文默认前置条件是,您的开发设备已...
- 一周热门
- 最近发表
- 标签列表
-
- mybatiscollection (79)
- mqtt服务器 (88)
- keyerror (78)
- c#map (65)
- resize函数 (64)
- xftp6 (83)
- bt搜索 (75)
- c#var (76)
- mybatis大于等于 (64)
- xcode-select (66)
- httperror403.14-forbidden (63)
- logstashinput (65)
- hadoop端口 (65)
- dockernetworkconnect (63)
- esxi7 (63)
- vue阻止冒泡 (67)
- c#for循环 (63)
- oracle时间戳转换日期 (64)
- jquery跨域 (68)
- php写入文件 (73)
- java大写转小写 (63)
- kafkatools (66)
- mysql导出数据库 (66)
- jquery鼠标移入移出 (71)
- 取小数点后两位的函数 (73)