- 以这个语句为例子
- arr1=array(1, 2, 3)
- 左边:变量名=数组名
- 右边:数组,集合,多个元素集合,多个数据集合,
- 右边的单个内容,1,2,3 是数组的元素/下标变量
- 每个元素存储时,会标记1个(看不见的 )index 索引 下标
- Sub test_array1()
- Dim arr1()
- Dim arr2()
- arr1() = Range("c1:c13")
- arr2() = Range("c1:o1")
- For i = 1 To 13
- Debug.Print arr1(i, 1)
- Next i
- For i = 1 To 13
- Debug.Print arr2(1, i)
- Next i
- End Sub
举例:
dim arr1(5) as integer
dim arr2(2 to 6) as string
dim arr3(3,5) as integer
- 数组的维数 : 数组可以是1维,2维等等,但数组的维数和嵌套不同!
- 每个维数大小 : 每个维数的 lbound() to ubound()
- 数组存储数据的类型: 可以是单一的,也可以是variant 变化的
- 数组存储的内容 : 每个值的具体内容
- 完备(界定清晰)数组: 数组的维数,每个维度长度都确定的数组。这样的数组可以给单一元素赋值操作,但如果是静态数组,数组不能被整体赋值。
- 不完备(界定清晰)数组:数组的维数,每个维度长度不确定的数组,这样的数组可以整体赋值(变相确定数组维数和大小),但是没法单一元素赋值
- Sub try2()
- Dim arr1(5)
- Dim arr2()
- Dim arr3()
- ReDim arr4(2)
- arr1(0) = 1
- 'arr1 = array(1, 2, 3, 4, 5) '不能给数组赋值,是不能给静态数组整个赋值?
- 'arr1() = Array(0, 1, 2, 3, 4, 5)
- Debug.Print Array(1, 2, 3, 4, 5)(0)
- arr2() = Array(1, 2, 3)
- 'arr3(0) = 1 '数组使用前,必须先redim 界定清晰(并不就是静态数组, redim arr3(2)虽然是动态的,也是界定清晰的)才可以赋值和使用
- ReDim arr3(2)
- arr3(0) = 555
- Debug.Print arr3(0)
- arr3 = Array(10, 20, 30, 40, 50) '动态数组可以被整体赋值
- Debug.Print arr3(1)
- End Sub
- 静态 static 一般指 定义后不再可以修改的。在这里具体指 数组的维数,每个维数的大小不可改变
- 动态 dynamic 一般指 定义后,在运行代码过程中还可以被改变的。在这里具体指 数组的维数,每个维数的大小可改变
- 如果可以 dim arr1() as static 或 dim arr2() as dynamic 就很清晰,但VBA里不是这样
- 但是VBA里不是这样----和数组的变量类型无关。
- 静态数组:
- dim arr1(4) 这样就是静态数组
- 动态数组:
- dim arr1() 这样就是动态数组,dim arr1() 和 redim arr1() 联动
- redim arr2(3) 这样也可以动态定义,redim就是动态定义,不能redim arr1(5)
静态数组特点:
动态数组特点:
数组的数据类型
定义数组的数据类型的差别
- 直接VBA定义的数组,少数特殊
- array(1,2,3) array() 只能生成1维数组
- 而直接 dim arr1(i,j,k) 是3维数组,或更高维都可以。
- 来自工作表的数组,最多只可能是2维数组,不可能是3维数组(少数特殊情况下是一维数组)
- [{}] 这个类[a1:c10] 和 range("a1:c10") 其实就是类工作表的区域
- [{1,2,3}] 是1维数组, [{1,2,3;4,5,6}] 是2维数组, [{1,2,3;4,5,6;7,8,9}] 并不是3维数组,而是2维数组
- range("a1") range("a1:a10") range("a1:c10") 都是二维数组 虽然EXCEL也会行列首尾相连,视为一维数组,但是还是当二维数组来的准确
- 用transpose 转化1列为1行,只是1维数组,而不是二维数组,这个很难记住。我觉得还是不用transpose 全当二维数组用来的准确
- Sub try4()
- a = [{1,2,3}]
- Debug.Print a(2)
- b = [{1,2,3;4,5,6}]
- Debug.Print b(1, 1)
- c = [{1,2;3,4;5,6}]
- Debug.Print c(3, 2)
- Debug.Print "数组区域如果是来自EXCEL的1行或1列,本质是2维数组,但EXCEL会把区域先行后列前后连接为1个1维数组,也可以看做1维度"
- Debug.Print Range("a1:a3")(3)
- Debug.Print Range("a1:a3")(3, 1)
- Debug.Print Range("a1:c1")(3)
- Debug.Print Range("a1:c1")(1, 3)
- Debug.Print "取的EXCEL表的区域,也可以自动前后组合为1个1维数组"
- Debug.Print Range("a1:c2")(5)
- Debug.Print Range("a1:c2")(2, 2)
- Debug.Print "单行但列也可以trasnpose"
- Debug.Print Range("a1:a3")(3)
- Debug.Print Range("a1:a3")(3, 1)
- Debug.Print Application.Transpose(Range("a1:a3"))(3)
- 'Debug.Print Application.Transpose(Range("a1:a3"))(1, 3) '工作表的1列组被transpose为1行,只被识别为1维数组,记不住!还不如不transpose 当二维数组用简单,真麻烦
- 'd = Application.Transpose(Range("a1:a3"))
- 'Debug.Print d(1, 3)
- 'Debug.Print Application.Transpose(Range("a1:a3"))(1, 3)
- Debug.Print Application.Transpose(Application.Transpose(Range("a1:a3")))(3, 1)
- End Sub
举例
- dim arr1() 数组只能dim 一次,否则就是重复dim定义数组了
- redim 是动态定义, redim时,必须带上维数,长度等
- Sub try6()
- Dim arr1()
- ReDim arr1(5)
- arr1(3) = 111
- ReDim Preserve arr1(6)
- Debug.Print arr1(3)
- ReDim Preserve arr1(10) '因为1维数组只1维,用preserve 保持1维,随便改大小
- Debug.Print arr1(3)
- 'ReDim Preserve arr1(2 To 12) '因为1维数组只1维,用preserve 保持1维,但可以改变上界,扩大缩小都可以
- 'Debug.Print arr1(3)
- ReDim Preserve arr1(0 To 9) '也可以缩小
- Debug.Print arr1(3)
- 'ReDim Preserve arr1(1 To 15) '用preserve 不能改变index的下界限
- 'Debug.Print arr1(3)
- ReDim Preserve arr1(0 To 2) '因为1维数组只1维,用preserve 保持1维,但如果preserve 掉了老数据,则可能取不到 arr1(3)
- 'Debug.Print arr1(3) ' 这样取不到arr1(3)
- 'ReDim Preserve arr1(5, 5) ' 会提示下标越界,因为用了preserve关键字,则只能改变最后一维的大小,而不能改变维数
- 'Debug.Print arr1(3, 1)
- ReDim arr1(5, 5) '不用preserve 则 redim 随便改
- Debug.Print arr1(3, 1)
- End Sub
例子
- Sub try1()
- Dim arr1()
- Dim arr2(1 To 3)
- ReDim arr3(1, 5)
- ReDim arr1(2)
- arr1(0) = 1
- arr2(1) = 55
- arr3(1, 1) = 666
- a = arr1
- c = arr1()
- ReDim arr1(5)
- 'ReDim c(6) '变量a,b.c.d等只是指向数组,本身还是个变量,并不是数组
- b = arr3
- d = arr3()
- ReDim arr3(2, 6)
- 'ReDim b(2, 6) '变量a,b.c.d等只是指向数组,本身还是个变量,并不是数组
- Debug.Print arr1(0)
- Debug.Print arr2(1)
- Debug.Print arr3(1, 1)
- Debug.Print a(0)
- Debug.Print b(1, 1)
- Debug.Print c(0)
- Debug.Print d(1, 1)
- c = "abc" '变量a,b.c.d还是变量,还可以改变其指向的内容
- Debug.Print c
- End Sub
不同的数组
VBA的数组定义
来源于工作表的数组定义
- Option Explicit
- Sub testArr1()
- 'Dim arr1() As Integer '这样定义数组是不够的,只定义了是数组,没定义维数和大小,可以试试这样会在赋值时报错
- Dim arr1(3) As Integer '定义为integer了,默认至少是0,而不是空
- Dim i
- arr1(0) = 0
- arr1(1) = 1
- arr1(2) = 2
- 'arr1(3) = "abc" '这样会报类型不匹配
- For i = LBound(arr1, 1) To UBound(arr1, 1)
- Debug.Print arr1(i)
- Next
- End Sub
- Sub testArr2()
- '静态数组,静态在维数不变,长度不变,具体的某个内容可以变化
- 'Dim arr2 As Variant '错误写法
- Dim arr2(2) As Variant '定义了一个静态数组,且为存储为变量类型
- Dim i
- arr2(0) = 1
- arr2(1) = "a"
- For i = LBound(arr2, 1) To UBound(arr2, 1)
- Debug.Print arr2(i)
- Next
- End Sub
- Sub try2()
- Dim arr1(5)
- Dim arr2()
- Dim arr3()
- ReDim arr4(2)
- arr1(0) = 1
- 'arr1 = array(1, 2, 3, 4, 5) '不能给数组赋值,是不能给静态数组赋值?
- arr2() = array(1, 2, 3)
- 'arr3(0) = 1 '数组使用前,必须先redim 界定清晰(并不就是静态数组, redim arr3(2)虽然是动态的,也是界定清晰的)才可以赋值和使用
- ReDim arr3(2)
- arr3(0) = 1
- End Sub
特别是动态数组,使用前必须先redim() 数组大小后才可以使用
- Sub test4()
- Dim arr1()
- ReDim arr1(11) '不redim会报错
- j = 1 'j=1也不会出错,但是arr1(0)会为空,不会被赋值
- For i = 1 To 11 Step 1
- If Not IsEmpty(Cells(i, 1)) Then
- arr1(j) = Cells(i, 1)
- j = j + 1
- End If
- Next i
- For j = 0 To UBound(arr1())
- Cells(j + 1, 9) = arr1(j) '单元格得从1开始,arr()得从0开始
- Next j
- End Sub
静态数组的数组名不能被(整体)赋值,只有 数组的元素,变量,对象可以被赋值
- Sub test001()
- Dim arr1(3) '如果已经声明为数组名了,arr1就代表arr1(),以后就不能给数组赋值
- Dim arr2 As Variant '相当于dim arr2
- Dim arr3 As Object
- 'arr1 = Range("a1:c1") '不能给数组整体赋值? 只能给数组里的元素赋值?arr1 = Range("a1:c1").value 也不行
- arr1(0) = Range("a1") '可以给数组的某个元素赋值
- arr2 = Range("a1:c1") '可以给变量赋值,赋予这个变量整个数组
- Set arr3 = Range("a1:c3") '可以把EXCEL的range 赋值给变量,或对象。然后默认都成为了2维数组。
- Range("b2:c2") = 9999
- Debug.Print "arr1(0)=" & arr1(0)
- Debug.Print "arr2(1,1)=" & arr2(1, 1)
- Debug.Print "arr3(1,1)=" & arr3(1, 1)
- End Sub
- Sub test1002()
- Dim arr1(10)
- Dim arr2()
- Dim arr3
- '如果先定义为静态数组
- arr1(0) = "a" '注意如果写成arr1(0)=a ,赋值内容其实为空,因为变量是a,未赋值。
- arr1(1) = 1001
- For Each i In arr1
- Debug.Print i & " ";
- Next
- Debug.Print
- 'arr1 = Range("a1:a11") '不能给数组赋值,其实就是不能整体赋值
- For Each i In arr1
- Debug.Print i & " ";
- Next
- Debug.Print
- '如果先定义为动态数组,也很灵活
- arr2 = Range("a1:a5")
- For Each i In arr2
- Debug.Print i & " ";
- Next
- Debug.Print
- arr2 = Range("b1:b7")
- For Each i In arr2
- Debug.Print i & " ";
- Next
- Debug.Print
- '变量是很灵活的
- arr3 = Range("a1:a3")
- For Each i In arr3
- Debug.Print i & " ";
- Next
- Debug.Print
- arr3 = Range("b1:b5") 'arr3是变量,可以改变维度,大小都行
- For Each i In arr3
- Debug.Print i & " ";
- Next
- Debug.Print
- End Sub
1维下限 lbound(arr,1) lbound(arr)
2维下限 lbound(arr,2)
3维下限 lbound(arr,3)
- Sub 测试1()
- Dim arr1 As Variant
- arr1 = Range("a1:c4")
- Debug.Print arr1(3, 3)
- Debug.Print LBound(arr1)
- Debug.Print UBound(arr1)
- Debug.Print LBound(arr1, 2) '二维数组,第1维默认是行数,往下数!
- Debug.Print UBound(arr1, 2) '二维数组, array(row,column)
- Sub 测试2()
- Dim arr2()
- arr2 = Range("a1:c4")
- Debug.Print arr2(3, 3)
- Debug.Print LBound(arr2)
- Debug.Print UBound(arr2)
- Debug.Print LBound(arr2, 2)
- Debug.Print UBound(arr2, 2)
- End Sub
- Sub 测试3()
- Dim arr2()
- arr2() = Range("a1:c4")
- Debug.Print arr2(3, 3)
- Debug.Print LBound(arr2)
- Debug.Print UBound(arr2)
- Debug.Print LBound(arr2, 2)
- Debug.Print UBound(arr2, 2)
- End Sub
- End Sub
- Sub t3()
- Dim arr(10) As String
- For i = 1 To 10 Step 1
- arr(i) = i
- Debug.Print (arr(i))
- Next i
- Debug.Print arr(5)
- Debug.Print arr(0) '不显示下标越界
- Debug.Print arr(11) '会显示下标越界
- End Sub
- Sub t3()
- Dim arr5(1 To 5) As Integer
- ReDim arr5(1 To 10) As String '不能对静态数组redim改变大小
- End Sub
- Sub t3()
- Dim arr3() As Integer '如果定义dim arr3 as integer 会成为一个变量
- Dim arr4() As Integer
- For i = 1 To 5 Step 1
- ReDim arr3(1 To i) '使用数组的内容之前,必须先redim 否则会显示下标越界
- ReDim arr4(1 To i)
- arr3(i) = i
- arr4(i) = i
- Debug.Print (arr3(i))
- Debug.Print (arr4(i))
- Next i
- End Sub
- Sub t4()
- Dim arr2()
- Rem Dim arr2(5, 6) '使用动态数组 redim就不要和 静态数组定义格式混用
- For i = 0 To 5 Step 1
- For j = 0 To 6 Step 1
- ReDim arr2(0 To i, 0 To j) '动态数组,必须在使用前redim '如果要用静态数组也可以,但不要再redim了!
- arr2(i, j) = i + j
- Debug.Print arr2(i, j)
- Next j
- Next i
- Sub t3()
- Rem Dim arr6 As Integer
- arr6 = Range("a1:a5")
- Debug.Print arr6(1, 1)
- Debug.Print arr6(2, 1)
- Debug.Print arr6(3, 1)
- Debug.Print arr6(4, 1)
- Debug.Print arr6(5, 1)
- End Sub
- Sub t4()
- Dim arr1(0 To 4, 0 To 5) As Integer
- arr1(0, 0) = 999
- Debug.Print arr1(0, 0)
- End Sub
定义静态3维数组
- Sub t4()
- Dim arr3(3, 4, 5)
- arr3(0, 0, 0) = 888
- Debug.Print arr3(0, 0, 0)
- End Sub
定义动态3维数组
- Sub test1001()
- Dim arr1()
- m = 1
- For i = 1 To 3
- For j = 1 To 3
- For k = 1 To 3
- ReDim arr1(i, j, k)
- arr1(i, j, k) = m
- Debug.Print "arr1(i, j, k)=" & arr1(i, j, k)
- m = m + 1
- Next
- Next
- Next
联系客服