VBA数组与变量

|
Document-edit Created with Sketch.
|

VBA中,数组(Array)集合(Collection) 是用于批量存储数据的容器。

数组(Array):相同类型数据的有序集合

数组是相同数据类型的元素组成的有序列表,每个元素通过「索引」(位置编号)访问。
特点:大小可固定(静态)或动态调整,访问速度快,适合存储同类型数据(如多个数字、多个字符串)。

静态数组(大小固定)

声明时直接指定大小,一旦创建不能改变长度。
语法
Dim 数组名(起始索引 To 结束索引) As 数据类型

VBA默认索引从0开始,但建议显式写1 To n(更符合日常习惯,比如对应Excel的行号)。

示例:用静态数组存储5个学生的成绩并计算平均分

Sub 静态数组示例()
    ' 声明一个存储整数的静态数组,包含5个元素(索引1到5)
    Dim 成绩(1 To 5) As Integer
    Dim 总和 As Integer
    Dim 平均分 As Single
    Dim i As Integer
    
    ' 给数组赋值(模拟5个学生的成绩)
    成绩(1) = 85
    成绩(2) = 92
    成绩(3) = 78
    成绩(4) = 90
    成绩(5) = 88
    
    ' 循环计算总和
    总和 = 0
    For i = 1 To 5
        总和 = 总和 + 成绩(i)
    Next i
    
    ' 计算平均分
    平均分 = 总和 / 5
    MsgBox "5个学生的平均分是:" & 平均分  ' 输出:86.6
End Sub

2. 动态数组(大小可变)

声明时不指定大小,后续根据需要用ReDim调整长度(可多次调整)。
语法

  1. 先声明:Dim 数组名() As 数据类型
  2. 再定义大小:ReDim 数组名(起始索引 To 结束索引)

示例:动态数组存储不确定数量的姓名

Sub 动态数组示例()
    ' 声明动态数组(不指定大小)
    Dim 姓名() As String
    Dim 人数 As Integer
    Dim i As Integer
    
    ' 让用户输入人数(动态确定数组大小)
    人数 = InputBox("请输入人数:")
    
    ' 定义数组大小(1到输入的人数)
    ReDim 姓名(1 To 人数)
    
    ' 循环输入每个人的姓名
    For i = 1 To 人数
        姓名(i) = InputBox("请输入第" & i & "个人的姓名:")
    Next i
    
    ' 循环输出所有姓名
    For i = 1 To 人数
        MsgBox "第" & i & "个人的姓名是:" & 姓名(i)
    Next i
End Sub

数组的关键要点:

  • 元素类型必须一致(如全是Integer或全是String);
  • 索引是“位置编号”,必须在声明的范围内(否则会报错“下标越界”);
  • 适合存储数量固定或可预测的数据(如Excel表格的某一列数据)。

集合(Collection):灵活的多类型数据容器

集合是一种更灵活的容器,可存储不同类型的数据(如同时存数字、字符串、对象),大小自动调整,支持用“键”(类似名字)快速访问元素。
特点:无需预先定义大小,支持键值对,适合存储类型复杂、数量不确定的数据。

集合的基本操作

  1. 声明集合Dim 集合名 As New CollectionNew表示创建集合对象);
  2. 添加元素集合名.Add 元素值, 键(键是可选的,相当于给元素起个唯一的名字);
  3. 访问元素集合名.Item(索引或键)(索引从1开始,键必须唯一);
  4. 删除元素集合名.Remove(索引或键)
  5. 获取元素数量集合名.Count(返回集合中元素的总数)。

示例:用集合管理学生信息(姓名+年龄,支持按姓名访问)

Sub 集合示例()
    ' 声明一个集合(用于存储学生信息)
    Dim 学生集合 As New Collection
    Dim 学生信息 As String  ' 临时存储单个学生的信息
    Dim i As Integer
    
    ' 1. 向集合添加3个学生(元素是“姓名-年龄”字符串,键是姓名)
    学生集合.Add "张三-18", "张三"  ' 键为“张三”,方便后续直接用姓名访问
    学生集合.Add "李四-19", "李四"
    学生集合.Add "王五-20", "王五"
    
    ' 2. 用“键”访问指定学生(比如访问“李四”)
    MsgBox "李四的信息:" & 学生集合.Item("李四")  ' 输出:李四-19
    
    ' 3. 用“索引”遍历所有学生(索引从1开始)
    For i = 1 To 学生集合.Count
        MsgBox "第" & i & "个学生:" & 学生集合.Item(i)
    Next i
    
    ' 4. 删除“王五”(用键删除)
    学生集合.Remove ("王五")
    MsgBox "删除王五后,剩余人数:" & 学生集合.Count  ' 输出:2
End Sub

集合的关键要点:

  • 元素类型可以不同(比如同时存IntegerStringRange对象);
  • 键必须唯一(重复键会报错),索引从1开始;
  • 适合存储类型复杂、数量动态变化的数据(如临时管理多个不同类型的对象)。

数组 vs 集合:怎么选?

场景 选数组 选集合
数据类型 所有元素类型相同 元素类型可不同
大小是否固定 静态数组固定,动态数组可调整 自动调整,无需预先定义
访问方式 只能用索引 可用索引或键(更灵活)
效率 访问速度快(适合大量数据) 效率稍低(适合少量/复杂数据)

建议

  • 若数据是同类型(如全是成绩、全是姓名),优先用数组;
  • 若数据类型复杂(如混合数字、字符串、对象),或需要用“名字”快速访问,优先用集合。

变量类型

变量类型 内存占用(字节) 描述 优化建议
Byte 1 无符号整数,范围 0~255 处理二进制数据或小范围整数时优先使用,减少内存占用
Boolean 2 布尔值,True(-1)或 False(0) 避免用Variant存储布尔值,直接声明为Boolean,节省内存
Integer 2 有符号整数,范围 -32,768~32,767 仅当确定数值在此范围内时使用;现代系统中优先考虑Long(减少溢出风险)
Long 4 有符号整数,范围 -2,147,483,648~2,147,483,647 大多数整数计算优先使用,平衡内存和溢出风险,效率优于Integer
Single 4 单精度浮点数,精度约6-7位,范围 ±1.401298E-45~±3.402823E38 不需要高精度时使用(如科学计算),避免用于财务等需精确值的场景
Double 8 双精度浮点数,精度约15-17位,范围 ±4.94065645841247E-324~±1.79769313486232E308 需较高精度的浮点数计算使用,比Single精度高但内存增加
Currency 8 货币类型,精度到小数点后4位,范围 -922,337,203,685,477.5808~922,337,203,685,477.5807 财务/货币计算优先使用,避免浮点数误差(如Single/Double的精度问题)
Decimal 14 高精度小数,精度28-29位,需通过Variant声明(如 Dim x As Variant: x = CDec(0) 仅在需要极高精度时使用(如精密测量),因内存占用高,避免常规场景
String(定长) 等于指定长度(每个字符1字节,ANSI编码) 固定长度字符串,声明方式 Dim s As String * n(n为长度) 已知字符串长度固定时使用,比变长String更节省内存(无指针开销)
String(变长) 4(指针) + 字符数(每个字符1字节,ANSI) 长度可变的字符串,默认声明方式 Dim s As String 字符串长度不固定时使用;避免用字符串存储日期/数值(改用Date/数值类型)
Date 8 日期时间类型,范围 100-1-1~9999-12-31,内部存储为双精度浮点数 存储日期时间必须用Date类型,比字符串存储更高效(节省内存且便于计算)
Object 4(32位系统)/ 8(64位系统) 对象引用,指向具体对象(如Worksheet、Range) 及时用 Set obj = Nothing 释放未使用的对象,减少内存泄漏;避免未初始化对象
Variant 16(空/数值);更多(字符串/对象等) 可变类型,可存储任何数据,默认未声明变量的类型 尽量避免使用,必须用时明确存储类型;优先用具体类型代替(大幅减少内存)

附录

参考文章

Licensed under CC BY-NC-SA 4.0 转载请留言告知
最后更新于 2025-10-23 21:33