数组
创建数组:
Dim 数组名(数组元素上下角标)[As 元素类型]
eg. Dim MyArray (1 To 3) As Integer
注意:1.如果不指定元素类型,则是Variant类型
向数组赋值:
eg.
MyArray(1) = 100
MyArray(2) = 200
MyArray(3) = 300
访问数组元素:
Debug.Print MyArray(2)
Debug.Print MyArray(2),MyArray(3)
遍历数组:
可以通过LBound和UBound动态获取数组的上下角标
eg. 1. Debug.Print LBound(MyArray),UBound(MyArray)
2. For Index = LBound(MyArray) To UBound(MyArray)
Debug.Print MyArray(Index)
Next Index
清除数组:
将数组中的数据进行重置
Erase MyArray
Option Base声明:
如果在声明变量时,只写了一个数字,表达的是最大的角标
注意:1. 声明需要放到最上方
2.默认最小角标就是0;只能设置0或1,设置其他值会报错
多维数组:
创建多维数组:
Option Base 1
Dim MyArray(2,3) As Integer => 创建两行三列数组
向多维数组赋值:
MyArray(1,1) = 10
MyArray(1,2) = 20
MyArray(1,3) = 30
MyArray(2,1) = 40
MyArray(2,2) = 50
MyArray(2,3) = 60
访问元素:
Debug.Print MyArray(2,2)
遍历二维数组,循环嵌套:
Dim RowNo As Integer,ColNo As Integer
For RowNo = 1 To 2
For ColNo = 1 To 3
Debug.Print MyArray(RowNo,ColNo)
Next ColNo
Next RowNo
遍历多维数组:
LBound(Array,n): 表示n维数组的最小角标
UBound(Array,n): 表示n维数组的最大角标
eg.
Dim MyArray(2,4) As Integer
MyArray(1,1) = 10
MyArray(1,2) = 20
MyArray(1,3) = 30
MyArray(2,1) = 40
MyArray(2,2) = 50
MyArray(2,3) = 60
For RowNo = LBound(MyArray,1) To UBound(MyArray,1) //一维角标最小值 ~ 一维角标最大值 1~2
// n省略(维度省略)默认是一维 “ For RowNo = LBound(MyArray) To UBound(MyArray) ”
For ColNo = LBound(MyArray,2) To UBound(MyArray,2) //二维角标最小值 ~ 二维角标最大值 1~3
Debug.Print MyArray(RowNo, ColNo)
Next ColNo
Next RowNo
For Each ... Next 循环语句:
每一次循环获取MyArray数组中某个空间的值,并且赋值给Num变量
For Each 变量 in 数组
循环体
Next 变量
注:1. ForEachNext循环其中的变量只能是Variant类型
2. ForEachNext循环语句只能遍历一维数组,无法遍历多维数组
3. Next 后面的变量,可写可不写
eg.
Sub ForEachNext循环()
Dim MyArray(1 To 3) As Integer
MyArray(1) = 10
MyArray(2) = 20
MyArray(3) = 30
Dim Num As Variant
For Each Num In MyArray
Debug.Print Num
Next Num
End Sub
动态数组:
创建动态数组:
Dim 数组名()[As 元素类型]
重新调整数组大小:
ReDim [Preserve] 数组名(数组元素上下角标,...)
注:1. Redim可以调整数组大小和维度 但无法重新指定数据类型
eg.
Sub 一维动态数组()
Dim MyDynArray() As Integer
ReDim MyDynArray(1 To 3, 1 To 4) //可以调整动态数组的大小,维度
MyDynArray(1) = 10
MyDynArray(2) = 20
MyDynArray(3) = 30
End Sub
2. ReDim调整动态数组的时候,会把之前的数组的数据进行重置
如何解决:添加Preserve:保留之前的数组数据
eg.
Sub 一维动态数组()
Dim MyDynArray() As Integer
ReDim MyDynArray(1 To 3)
MyDynArray(1) = 10
MyDynArray(2) = 20
MyDynArray(3) = 30
Dim Num As Variant
ReDim MyDynArray(1 To 4) // ReDim Preserve MyDynArray(1 To 4) 动态扩展,但不要把原来数据抹除
MyDynArray(4) = 40
For Each Num In MyDynArray
Debug.Print Num
Next
End Sub
=> 0 => 10
0 20
0 30
40 40
3. 如果使用了ReDim并且添加了Preserve,只能调整最后一个维度的大小
eg.
Sub 二维动态数组()
Dim MyDynArray() As Integer
ReDim MyDynArray(1 To 3)
MyDynArray(1) = 10
MyDynArray(2) = 20
MyDynArray(3) = 30
ReDim MyDynArray(1 To 2, 1 To 3)
MyDynArray(1,1) = 10
MyDynArray(1,2) = 20
MyDynArray(1,3) = 30
MyDynArray(2,1) = 40
MyDynArray(2,2) = 50
MyDynArray(2,3) = 60
Dim RowNo As Integer,ColNo As Integer
For RowNo = LBound(MyDynArray) To UBound(MyDynArray)
For ColNo = LBound(MyDynArray,2) To UBound(MyDynArray,2) //二维
Debug.Print MyDynArray(RowNo,ColNo)
Next ColNo
Next RowNo
ReDim Preserve MyDynArray(1 To 2, 1 To 4)
MyDynArray(1,4)=70
MyDynArray(2,4)=80
For RowNo = LBound(MyDynArray) To UBound(MyDynArray)
For ColNo = LBound(MyDynArray,2) To UBound(MyDynArray,2) //二维
Debug.Print MyDynArray(RowNo,ColNo)
Next ColNo
Next RowNo
End Sub
=> 10
20
30
70
40
50
60
80
Array函数:
使用Array函数创建一维数组
Dim MyArray As Variant
MyArray = Array(1,2,3,4,5)
eg.
创建的一维数组默认从0角标开始:
Sub 使用Array函数创建一维数组()
Dim MyArray As Variant
MyArray = Array(10,20,30,40,50)
Dim Index As Integer
For Index =LBound(MyArray) To UBound(MyArray)
Debug.Print MyArray(Index)
Next Index
End Sub
创建的一维数组默认从1角标开始:
Option Base 1
Sub 使用Array函数创建一维数组()
Dim MyArray As Variant
MyArray = Array(10,20,30,40,50)
Dim Index As Integer
For Index =LBound(MyArray) To UBound(MyArray)
Debug.Print MyArray(Index)
Next Index
End Sub
使用Array函数模拟创建多维数组
以二维数组为例
Dim MyArray As Variant
MyArray = Array(Array(10,20,30),Array(40,50,60))
MyArray(1)(1) //MyArray(1)这个一维数组的第一个元素
//MyArray(1) MyArray的第一个元素,只不过它又是一个数组
遍历使用Array函数模拟创建的二维数组
Sub 使用Array函数模拟创建二维数组()
Dim MyArray As Variant
MyArray = Array(Array(10,20,30),Array(40,50,60))
Dim i As Integer,j As Integer
For i = LBound(MyArray) To UBound(MyArray)
For j = LBound(MyArray(i)) To UBound(MyArray(i))
Debug.Print MyArray(i)(j)
Next j
Next i
End Sub
//MyArray(i)(j)访问MyArray中的数组元素中的第j个元素
注:使用Array函数创建的数组是固定大小的,不能使用ReDim重新调整数组的大小
练习1 —— 获取数组最大值和最小值:
Sub 查找最大值和最小值()
Dim MaxValue As Integer,MinValue
Dim NumArray As Variant
NumArray = Array(3,8,2,5,10)
’ LBound(NumArray):获取一维数组的最小角标;NumArray(LBound(NumArray)):获取一维数组的最小角标所对应的值
MaxValue = NumArray(LBound(NumArray))
MinValue = NumArray(LBound(NumArray))
Dim Index As Integer
’从第二个角标到最后一个角标,可以针对这些角标中的每个空间的数据都和MaxValue的值进行比较
For Index = LBound(NumArray)+ 1 To UBound(NumArray)
’如果某个角标所对应的值大于MaxValue所存储的值,将这个数值存储到MaxValue变量中;否则,什么都不做
If NumArray(Index) > MaxValue Then
MaxValue = NumArray(Index)
End If
If NumArray(Index) < MinValue Then
MinValue = NumArray(Index)
End If
Next Index
Debug.Print "最大值:" & MaxValue
Debug.Print "最小值:" & MinValue
End Sub
练习2 —— 获取二维数组的最大值:
扩展:记录最大值的位置(所处的行列角标)
eg.
Sub 查找二维数组中的最大值()
Dim Matrix (1 To 3,1 To 3)As Integer
Matrix(1,1) = 1
Matrix(1,2) = 5
Matrix(1,3) = 3
Matrix(2,1) = 4
Matrix(2,2) = 2
Matrix(2,3) = 9
Matrix(3,1) = 7
Matrix(3,2) = 8
Matrix(3,3) = 6
// 多行代码放到一行上,可以使用英文冒号进行分隔
Matrix(1,1) = 1: Matrix(1,2) = 5: Matrix(1,3) = 3
Matrix(2,1) = 4: Matrix(2,2) = 2: Matrix(2,3) = 9
Matrix(3,1) = 7: Matrix(3,2) = 8: Matrix(3,3) = 6
Dim MaxValue As Integer
MaxValue = Matrix(1,1)
Dim RowNo As Integer,ColNo As Integer
Dim MaxValueRowNo As Integer, MaxValueColNo As Integer
MaxValueRowNo = 1
MaxValueColNo = 1
For RowNo = LBound(Matrix,1) To UBound(Matrix,1)
For ColNo = LBound(Matrix,2) To UBound(Matrix,2)
If Matrix(RowNo,ColNo) > MaxValue Then
MaxValueRowNo = RowNo
MaxValueColNo = ColNo
MaxValue = Matrix(RowNo,ColNo)
End If
Next ColNo
Next RowNo
Debug.Print "最大值:" & MaxValue
Debug.Print "最大值的行角标:" & MaxValueRowNo
Debug.Print "最大值的列角标:" & MaxValueColNo
End Sub
练习3 —— 计算录入数据的均值:
Sub 计算学生平均成绩()
Dim Grades() As Integer //创建动态数组,保存用户每次录入的数据
Dim NewGrade As Integer //用于保存用户最新录入的成绩数据
Dim InputContent As String //保存用户录入的信息
ReDim Grades(1 To 1) //动态数组先初始化,初始化动态数组为一行一列的数组
Do
InputContent = InputBox("输入新成绩(输入"结束"终止输入,执行计算程序)")
If InputContent = "结束" Then
Exit Do
Else
NewGrade = VBA.CInt(InputContent) //这里需要把数字内容的字符串转换为整数,C:Convert进行转换,Int:Integer,转换为整数
Grades(UBound(Grades)) = NewGrade //把转换后的数字存储到动态数组中
ReDim Preserve Grades(1 To UBound(Grades)+1) //扩大一个格子的空间,为下次做准备
End If
Loop
//当用户输入结束后,就需要遍历动态数组,把所有成绩求和,得到总成绩,方便我们最终计算平均值
Dim Num As Variant,GradeSum As Integer
For Each Num In Grades
GradesSum = GradesSum + Num
Next
Dim GradesAvg As Double
If UBound(Grades) = 1 Then
MsgBox "没有录入一次学生成绩数据,计算平均值没有意义"
Else
GradesAvg = GradesSum / (UBound(Grades) - LBound(Grades)) //如果用户直接输入结束,会导致报错,1-1=0
Debug.Print "平均成绩为:" & GradesAvg
End If
End Sub
//原=> 50 0 1
100
90
80
0 4 5