一、数组
1.1. 初始值数组
这种数组在创建的同时就需要把元素填充好,比较适合元素内容不多、已知、固定时使用,其语
法为: 变量 = Array(元素1, 元素2, 元素n)
,然后通过元素坐标来访问数组中的元素,坐标从 0 开始计算,
既第一个元素的坐标是 0 ,第二个元素坐标是 1,第三个元素坐标是2 ,以此类推
示例代码
Sub main()
'定义初始值数组
Dim items
items = Array(1, 2, 3, 4, 5)
'访问数组中坐标为2的元素,既元素值3
Debug.Print items(2)
End Sub
1.2. 静态数组
这种一般用在元素内容无法确定,需要后期填充,但元素数量确定的场景,有两种定义语法:
- 通过
Dim 变量名(终点坐标)
定义,这种定义方式起始坐标默认是 0 - 通过
Dim 变量名(起始坐标 To 终点坐标)
定义,这种定义方式自己指定起点和终点坐标
示例代码
Sub main()
'起始坐标默认为0
Dim items(5)
items(0) = 1
items(1) = 2
items(2) = 3
items(3) = 4
items(4) = 5
Debug.Print items(2)
'自定义起始坐标
Dim items2(1 To 5)
items2(1) = 1
items2(2) = 2
items2(3) = 3
items2(4) = 4
items2(5) = 5
Debug.Print items2(2)
End Sub
1.3. 动态数组
这种一般用在元素内容和元素长度都不确定的场景,先用 Dim 变量名()
声明数组,然后当数组长度确定时,在通过
ReDim 变量名(起始坐标 To 终点坐标)
来设置数组长度
示例代码
Sub main()
Dim items()
ReDim items(1 To 5)
items(1) = 1
items(2) = 2
items(3) = 3
items(4) = 4
items(5) = 5
Debug.Print items(2)
End Sub
1.4. 二维数组
二维数组对于学习 vba 来说非常重要,既然学习 vba 的目的是为了扩展 Excel 的功能,那么就肯定避免不了和
单元格打交道,而 vba 中,很多选取单元格的函数,都是以二维数组的形式返回的
二维数组非常好理解,其本质就是数组的元素仍是数组,一般习惯将第一维中的每个元素称作行,第二维中的每个
元素称作列,一个三行三列的二维数组的结构大概如下图:
定义二维数组时要指定两个长度 :
- 第一维数组的长度,既数组有几行
- 每个二维数组的长度,既每行中有几列
其定义语法为: Dim 变更名( 一维数组起始坐标 To 一维数组终点坐标, 二维数组起始坐标 To 二维数组终点坐标)
示例代码
一个两行三列的数组,注意:二维数组在填充和取值时,要定位到列的坐标:
Sub main()
'定义两行三列的二维数组
Dim items(1 To 2, 1 To 3)
'为二维数组赋值
For x = 1 To 2
For y = 1 To 3
items(x, y) = x + y
Next y
Next x
'二维数组取值, 第一行第一列的值
Debug.Print items(1, 1)
End Sub
1.4.1. 单元格与二维数组
选取 Excel 中的单元格并赋值给二维数组,或将二维数组赋值到单元格都是 vba 开发中常见的操作
例1:选取三行三列的单元格到二维数组中
代码:
Sub main()
Dim items
items = Range("a1:c3")
End Sub
设置断点并运行,在本地窗口中验证 items 是否为三行三列的数组:
例2:将二维数组设置到单元格中
Sub main()
'设置二维数组
Dim items(1 To 2, 1 To 2)
items(1, 1) = "a1"
items(1, 2) = "b1"
items(2, 1) = "a2"
items(2, 2) = "b2"
'将二维数组设置到单元格中
Sheet1.Range("a1:b2") = items
End Sub
1.4.2. 一维数组导入单元格
将一维数组导入单元格的时候,需要用 Application.Transpose
将数组转换一下
Sub main()
'设置一维数组
Dim items(1 To 2)
items(1) = 1
items(2) = 2
'将一维数组设置到单元格中
Sheet1.Range("a1:a2") = Application.Transpose(items)
End Sub
1.5. 数组最大最小下标
一维数组
获取数组最小下标
Sub main()
Dim items(5 To 10)
Debug.Print LBound(items)
End Sub
获取数组最大下标
Sub main()
Dim items(5 To 10)
Debug.Print UBound(items)
End Sub
二维数组
获取数组第一维度最大下标
Sub main()
Dim items(5 To 10, 4 To 15)
Debug.Print UBound(items, 1)
End Sub
获取数组第二维度最大下标
Sub main()
Dim items(5 To 10, 4 To 15)
Debug.Print UBound(items, 2)
End Sub
1.6. 数组扩容
数组扩容需要先定义一个动态数组,然后通过 ReDim
和 Preserve
关键字对该动态数组进行扩容,扩容后会
保留数组内原来的数据
Sub main()
'定义动态数组
Dim items()
'对数组进行第一次扩容
ReDim Preserve items(1 To 2)
items(1) = 1
items(2) = 2
'对数组进行第二次扩容
ReDim Preserve items(1 To 3)
items(3) = 3
End Sub
1.7. 数组相关常用的函数
1.7.1. 清空数组
使用 Erase
关键字可以清空数组内的元素
Sub main()
'定义数组
Dim items(1 To 1)
items(1) = 1
Debug.Print items(1)
'清空数组
Erase items
Debug.Print items(1)
End Sub
1.7.2. 数组最大值
使用 Application.Max
函数,可以找到数组中值最大的元素
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = 5
items(2) = 3
items(3) = 1
items(4) = 2
items(5) = 4
'数组内最大值
Debug.Print Application.Max(items)
End Sub
1.7.3. 数组最小值
使用 Application.Min
函数,可以找到数组中值最小的元素
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = 5
items(2) = 3
items(3) = 1
items(4) = 2
items(5) = 4
'数组内最小值
Debug.Print Application.Min(items)
End Sub
1.7.4. 数组中第 N 大的值
使用 Application.Large
函数,可以找到数组中值第 N 大的元素
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = 50
items(2) = 30
items(3) = 10
items(4) = 20
items(5) = 40
'数组内第二大的值
Debug.Print Application.Large(items, 2)
End Sub
1.7.5. 数组中第 N 小的值
使用 Application.Small
函数,可以找到数组中值第 N 小的元素
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = 50
items(2) = 30
items(3) = 10
items(4) = 20
items(5) = 40
'数组内第二小的值
Debug.Print Application.Small(items, 2)
End Sub
1.7.6. 数组内容求和
使用 Application.Sum
函数,可以对数组中的所有元素进行求和
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = 50
items(2) = 30
items(3) = 10
items(4) = 20
items(5) = 40
'数组求和
Debug.Print Application.Sum(items)
End Sub
1.7.7. 数组中查找
使用 Application.WorksheetFunction.Count
函数,可以统计出数组内数值型元素的数量
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = "字符串"
items(2) = 30
items(3) = 10
items(4) = 20
items(5) = 40
'数组内数值型元素的数量为4个
Debug.Print Application.WorksheetFunction.Count(items)
End Sub
1.7.8. 统计数量
使用 Application.WorksheetFunction.CountA
函数,可以统计出数组内数值型和字符串型元素的总数量
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = "字符串"
items(2) = 30
items(3) = 10
items(4) = 20
items(5) = 40
'数组内数值型和字符型元素的数量为5个
Debug.Print Application.WorksheetFunction.CountA(items)
End Sub
1.7.10. 数组中查找
使用 Application.Match
函数,可以返回指定值在数组内对应的下标,第三个参数为返回第 N 次匹配的下标 ( 0:第一
次匹配的下标,1:第二次匹配的下标)
Sub main()
'定义数组
Dim items(1 To 5)
items(1) = "字符串"
items(2) = 30
items(3) = 10
items(4) = 20
items(5) = 40
'返回第一次匹配的元素下标 4
Debug.Print Application.Match(20, items, 0)
End Sub
1.7.11. 将字符串分割成数组
使用 VBA.Split
函数,可以按照分割符将字符串拆分成数组,下标从 0 开始
Sub main()
Dim items
'拆分成长度为3的数组,下标从 0 开始
items = VBA.Split("第1段-第2段-第3段", "-")
For Each Item In items
Debug.Print Item
Next Item
End Sub
二、字典
数据字典类似于其他开发语言中的 Map 结构,属于 Key/Value 集合,集合中 Key 不能重复
2.1. 创建字典和填入数据
利用 CreateObject("scripting.dictionary")
来创建一个字典,然后通过字典对象的 Add
方法来添加数据
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
End Sub
2.2. 字典取值
根据 key 在字典中查找其对应的值
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
'根据 key 在字典中取值
Debug.Print dic("数据1")
End Sub
通过字典对象的 items
属性,取得字典中全部的 key
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
'取得字典中全部的 key
Dim items
items = dic.items
For Each Item In items
Debug.Print Item
Next Item
End Sub
2.3. 修改字典内容
字典中不能添加重复的 key,但是可以对已有 key 对应的值进行修改
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
Debug.Print dic("数据1")
'修改字典中的数据
dic("数据1") = "这是修改后的数据"
Debug.Print dic("数据1")
End Sub
2.4. 统计字典内容数量
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
'统计字典内元素的数量
Debug.Print dic.Count
End Sub
2.5. 判断键在字典内是否存在
根据 key 在字典内查找,结果为布尔类型
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
'统计字典内元素的数量
Debug.Print dic.Exists("数据1")
End Sub
2.6. 将内容从字典内删除
利用字典对象的 Remove
方法,可以根据 key 将元素从字典中删除
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
Debug.Print dic.exists("数据1")
'根据 key 将元素从字典中删除
dic.Remove "数据1"
Debug.Print dic.exists("数据1")
End Sub
利用字典对象的 RemoveAll
方法,可以清空字典
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'向字典内添加数据
dic.Add "数据1", "这是数据1的值"
dic.Add "数据2", "这是数据2的值"
Debug.Print dic.exists("数据1")
'清空字典
dic.RemoveAll
Debug.Print dic.exists("数据1")
End Sub
2.7. 设置字典不许分大小写
在字典操作中,默认情况下 key 是区分大小写的,可以通过设置字典对象的 CompareMode
属性,让字典忽略 Key
的大小写
Sub main()
'声明字典
Dim dic
Set dic = CreateObject("scripting.dictionary")
'让字典忽略 key 的大小写
dic.CompareMode = vbTextCompare
'向字典内添加数据
dic.Add "a", "值"
Debug.Print dic.exists("A")
End Sub