【原创】VBA学习笔记(12)VBA的数组 array

一 数组 array

1.1 什么是数组?具体的例子

  • 以这个语句为例子
  • arr1=array(1, 2, 3)
  • 左边:变量名=数组名
  • 右边:数组,集合,多个元素集合,多个数据集合,
  • 右边的单个内容,1,2,3 是数组的元素/下标变量
  • 每个元素存储时,会标记1个(看不见的 )index 索引 下标

1.2 什么是数组,抽象的定义:数组也是变量,是一种可存储多个数据的特殊变量

  • VBA或其他语言里,变量是用来存储数据的。
  • 而一般来说,1个变量只能用来存储1个数据
  • 现在来了1个特例,有高手发明了数组的概念: 数组是一个特殊的变量,可以用来存储多个数据!(甚至是多维的多个数据!)
  • 数组就是多个单位/元素(element)有序的,连续存储在一起作为一个整体,统一叫1个名字(数组名)

1.3 数组的特点,index有序不重复,但数组的元素却可以重复

  • 什么叫有序?
  • 就是数组的内容存储是有序的
  • index 是有序(一般是从小到大)
  • index也应该是连续的,暂时没见过 index不连续的情况
  • index也不能重复
  • 但是数组存储的内容,是可以重复的
  1. 数组的index下标默认是从0开始的,比如split生成的,还有未指定index下标的,如 dim arr1(5)
  2. 但是数组的index下标也有从1开始的情况,比如range 赋值的变量,默认下标从1开始,如 arr2=range("b1:d5")
  3. 数组的index下标受控制的情况模块最前面 option base  -1
  4. 数组index下标最好自己定义好, 如  dim arr3(1 to 5)
  • Dim arr1(3)                      '其实是0-3,有4个元素
  • Dim arr1( 1 to 3)              '其实是1-3,有3个元素
  • Option base 1
  1. Sub test_array1()
  2. Dim arr1()
  3. Dim arr2()
  4. arr1() = Range("c1:c13")
  5. arr2() = Range("c1:o1")
  6. For i = 1 To 13
  7. Debug.Print arr1(i, 1)
  8. Next i
  9. For i = 1 To 13
  10. Debug.Print arr2(1, i)
  11. Next i
  12. End Sub

 

1.4 数组的核心内容:就4个: 维数,每个维度大小,数据类型,数据

举例:

dim arr1(5)  as integer

dim arr2(2 to 6) as string 

dim arr3(3,5) as integer

  1. 数组的维数                : 数组可以是1维,2维等等,但数组的维数和嵌套不同!
  2. 每个维数大小           : 每个维数的 lbound()  to  ubound()
  3. 数组存储数据的类型: 可以是单一的,也可以是variant 变化的
  4. 数组存储的内容        : 每个值的具体内容

 

2 数组的分类

  • 这些概念拿到前面说,是因为自己作为新手,发现很容易弄混概念,分不清什么静态数组,什么是界定清晰的数组?
  • 数组定义和 静态动态是相关的,
  • 数组赋值也是和这些概念相关的,比如,静态数组不能被整体赋值,动态数组赋值前,要先界定清晰 维数和大小等。

 

2.1 什么叫完备(界定清晰)的数组,什么叫不完备的数组?---主要是指 数组的维数,维数大小(一般不管数组的数据类型)

 

  • 完备(界定清晰)数组:    数组的维数,每个维度长度都确定的数组。这样的数组可以给单一元素赋值操作,但如果是静态数组,数组不能被整体赋值。
  • 不完备(界定清晰)数组:数组的维数,每个维度长度不确定的数组,这样的数组可以整体赋值(变相确定数组维数和大小),但是没法单一元素赋值
  • 举例
  • dim arr1(5) as integer  这个就是一个界定清晰的数组!    dim arr1(5) as integer  等价于 dim arr1(0 to 5) as integer 
  • dim arr2()  等价于    dim arr2 () as  variant  这个其实就没有界定 数组的 维数,每个维数的大小是不清晰的。
  1. Sub try2()
  2. Dim arr1(5)
  3. Dim arr2()
  4. Dim arr3()
  5. ReDim arr4(2)
  6. arr1(0) = 1
  7. 'arr1 = array(1, 2, 3, 4, 5) '不能给数组赋值,是不能给静态数组整个赋值?
  8. 'arr1() = Array(0, 1, 2, 3, 4, 5)
  9. Debug.Print Array(1, 2, 3, 4, 5)(0)
  10. arr2() = Array(1, 2, 3)
  11. 'arr3(0) = 1 '数组使用前,必须先redim 界定清晰(并不就是静态数组, redim arr3(2)虽然是动态的,也是界定清晰的)才可以赋值和使用
  12. ReDim arr3(2)
  13. arr3(0) = 555
  14. Debug.Print arr3(0)
  15. arr3 = Array(10, 20, 30, 40, 50) '动态数组可以被整体赋值
  16. Debug.Print arr3(1)
  17. End Sub

 

2.2 什么叫静态数组,动态数组 ( VBA里没有static 和 dynamic关键字,不好判断) 

  • 数组何谓静态,动态?
  • 数组的4个关键要素:维数,维数大小,数据类型,数据。
  • 数据肯定可以改变,这是变量的基本特点。而数据类型,在数组定义时已经显式的声明,或者缺省为 variant了
  • 所以数组可以动态改变就是指:数组的维数和每个维数大小是否可以改变
  • 静态还是动态,和数组的变量类型无关
  • 静态还是动态,不是dim的一定是静态数组,dim arr1() 是动态数组
  • 静态 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)

静态数组特点:

  • 静态数组不能再次dim,也不能redim
  • 静态数组不能在改变大小
  • 静态数组也不能被一个数组赋值(整体赋值)

动态数组特点:

  • 动态数组,可以被整体赋值为一个数组。
  • 动态数组如果想对某一个值进行赋值或修改,需要先把维数和维数大小声明清楚后才可以。

 

 

2.3 数组的数据类型:只是决定了,数组存储的数据的数据类型,和动态/静态无关

数组的数据类型

  • integer
  • string 
  • variant  (默认缺省) 可以存储变量的数组,而因为变量本身可以存储各种类型,所以数组可以存储各种类型的数据。 但是占据空间大。

定义数组的数据类型的差别

  • 如果定义为如下几种,所有元素都只能是这种类型的数据,否则会报错
  • 如果 dim arr1(3) as integer
  • 如果定义为 din  arr1() as variant 或 dim arr1() 缺省,都会默认为,可以存储变量的数组。

 

2.4 什么叫1维数组,什么叫2维数组?

 

  • 数组的维数
  • 1维数组,arr1(i)
  • 2维数组,arr2(i,j)
  • 3维数组,arr3(i,j,k)

 

 

  • 维度这个概念,一般是空间的概念
  • 我理解数组的维数,肯定是多维坐标轴能表示的,虽然不一定和多维空间联系起来。
  • 我理解多和维度是 相乘的关系。
  • 比如具体到EXCEL的数据,1维是行,2维是行*列,3维是 行*列*sheet名,4维是   行*列*sheets* workbooks
  •  
  • 直接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 全当二维数组用来的准确

 

  1. Sub try4()
  2. a = [{1,2,3}]
  3. Debug.Print a(2)
  4. b = [{1,2,3;4,5,6}]
  5. Debug.Print b(1, 1)
  6. c = [{1,2;3,4;5,6}]
  7. Debug.Print c(3, 2)
  8. Debug.Print "数组区域如果是来自EXCEL的1行或1列,本质是2维数组,但EXCEL会把区域先行后列前后连接为1个1维数组,也可以看做1维度"
  9. Debug.Print Range("a1:a3")(3)
  10. Debug.Print Range("a1:a3")(3, 1)
  11. Debug.Print Range("a1:c1")(3)
  12. Debug.Print Range("a1:c1")(1, 3)
  13. Debug.Print "取的EXCEL表的区域,也可以自动前后组合为1个1维数组"
  14. Debug.Print Range("a1:c2")(5)
  15. Debug.Print Range("a1:c2")(2, 2)
  16. Debug.Print "单行但列也可以trasnpose"
  17. Debug.Print Range("a1:a3")(3)
  18. Debug.Print Range("a1:a3")(3, 1)
  19. Debug.Print Application.Transpose(Range("a1:a3"))(3)
  20. 'Debug.Print Application.Transpose(Range("a1:a3"))(1, 3) '工作表的1列组被transpose为1行,只被识别为1维数组,记不住!还不如不transpose 当二维数组用简单,真麻烦
  21. 'd = Application.Transpose(Range("a1:a3"))
  22. 'Debug.Print d(1, 3)
  23. 'Debug.Print Application.Transpose(Range("a1:a3"))(1, 3)
  24. Debug.Print Application.Transpose(Application.Transpose(Range("a1:a3")))(3, 1)
  25. End Sub

 

举例

  • 一维数组
  • dim arr1(1)               '并且index从0开始
  • array(1,2,3,4,5)       '并且index从0开始
  • [{1,2,3}]                    '因为来自工作表,所以index从1开始

 

  • 二维数组
  • range("a1")
  • range("a1:a10")
  • [{1,2,3,4,5;6,7,8,9,10}]
  • [{1,2,3;4,5,6;7,8,9;7,8,9;7,8,9;7,8,9;7,8,9;7,8,9;7,8,9}]
  • dim arr1(3,5)             '并且index从0开始             

 

  • 三维数组
  • dim arr1(5,6,3)          '并且index从0开始             

 

2.4 什么叫嵌套数组

  • 数组作为其他数组的元素,叫嵌套数组,并不是多维数组
  • arr1=array(1,2,3)
  • arr2=array(arr1,1,2,3)

 

3 数组的定义

3.1  如何定义数组? 类定义变量

  • 定义变量
  • dim  a
  • 定义数组,需要带括号。
  • dim a() 
  • dim b(1,2)

 

3.2 数组定义有哪些方式?

  • 只有3种方式
  • dim 
  • dim 配合 redim
  • redim 

 

  • 声明数组需要用到 dim 和redim 
  • 声明静态数组
  • dim arr1(5)   或 dim arr1(5,3) 

 

  • 声明动态数组
  • dim arr1()
  • redim   用于过程级 声明动态数组变量,配合  dim arr1() 使用

 

3.3  dim的一定是静态数组,redim 一定是动态数组吗? NO,dim可以定义静态数组或动态数组

  • dim 可以定义静态/动态数组。
  • dim arr1()   数组只能dim 一次,否则就是重复dim定义数组了
  • redim 是动态定义, redim时,必须带上维数,长度等

 

  • 数组定义
  • dim 数组名()
  • dim arr1(4) 这样就是静态数组
  • dim arr1()    这样就是动态数组,dim arr1() 和  redim arr1() 联动

 

  • redim 其实算不上定义
  • 与 Dim 语句、Static 语句不同,ReDim 语句是一个可执行语句,由于这一语句,应用程序在运行时执行一个操作。
  • redim arr2(3)  
  • 注意,如果是 redim preserve 则只能修改数组的最后1维的大小,而且不能修改数组的维数!!
  • 只是redim 则很自由,随意

 

  1. Sub try6()
  2. Dim arr1()
  3. ReDim arr1(5)
  4. arr1(3) = 111
  5. ReDim Preserve arr1(6)
  6. Debug.Print arr1(3)
  7. ReDim Preserve arr1(10) '因为1维数组只1维,用preserve 保持1维,随便改大小
  8. Debug.Print arr1(3)
  9. 'ReDim Preserve arr1(2 To 12) '因为1维数组只1维,用preserve 保持1维,但可以改变上界,扩大缩小都可以
  10. 'Debug.Print arr1(3)
  11. ReDim Preserve arr1(0 To 9) '也可以缩小
  12. Debug.Print arr1(3)
  13. 'ReDim Preserve arr1(1 To 15) '用preserve 不能改变index的下界限
  14. 'Debug.Print arr1(3)
  15. ReDim Preserve arr1(0 To 2) '因为1维数组只1维,用preserve 保持1维,但如果preserve 掉了老数据,则可能取不到 arr1(3)
  16. 'Debug.Print arr1(3) ' 这样取不到arr1(3)
  17. 'ReDim Preserve arr1(5, 5) ' 会提示下标越界,因为用了preserve关键字,则只能改变最后一维的大小,而不能改变维数
  18. 'Debug.Print arr1(3, 1)
  19. ReDim arr1(5, 5) '不用preserve 则 redim 随便改
  20. Debug.Print arr1(3, 1)
  21. End Sub

 

3.4 数组定义的总结

  • 什么叫数组的定义? 定义什么?
  • 基础定义:就是把一个变量定义为数组
  • 完整定义,声明: 把1个变量定位为数组,并且声明数组的 维数,大小,数据类型!

 

  • 定义时可以完备,也可以不完备
  • 不完备的声明,把变量定义为数组,   如 dim arr1()  这种一般要和 redim arr1 配合使用
  • 比较完备的声明:把变量定义为数组的同时,也定义数组的维数,维数的大小,数组的数值类型     dim arr1(5)  as interger  或 redim  arr2(2) 


例子

  1. Sub try1()
  2. Dim arr1()
  3. Dim arr2(1 To 3)
  4. ReDim arr3(1, 5)
  5. ReDim arr1(2)
  6. arr1(0) = 1
  7. arr2(1) = 55
  8. arr3(1, 1) = 666
  9. a = arr1
  10. c = arr1()
  11. ReDim arr1(5)
  12. 'ReDim c(6) '变量a,b.c.d等只是指向数组,本身还是个变量,并不是数组
  13. b = arr3
  14. d = arr3()
  15. ReDim arr3(2, 6)
  16. 'ReDim b(2, 6) '变量a,b.c.d等只是指向数组,本身还是个变量,并不是数组
  17. Debug.Print arr1(0)
  18. Debug.Print arr2(1)
  19. Debug.Print arr3(1, 1)
  20. Debug.Print a(0)
  21. Debug.Print b(1, 1)
  22. Debug.Print c(0)
  23. Debug.Print d(1, 1)
  24. c = "abc" '变量a,b.c.d还是变量,还可以改变其指向的内容
  25. Debug.Print c
  26. End Sub


 

3.5 不同的数组,index的 下界 lbound() 默认值不同,VBA的数组一般默认是0,来自EXCEL表的默认为1

不同的数组

  • 数组函数定义的内容,arr1= array(1,2,5)
  • 数组可以是excel的range() 单位赋值而成的 变量/对象,如 arr1=range("a1:c10")
  • 比如这样也是数组 arr1=[{1,2,3}]
  • MS 出了一个 sequence() 函数,暂时还没用过

 

VBA的数组定义

  • 用VBA的一维数组函数array() 或者 dim  或者 redim 这几种方法,默认index从0开始
  • 当然 dim  或者 redim 可以声明从1开始或从其他开始
  • 比如 dim arr2(1 to 3) 或 option base 2 等等

来源于工作表的数组定义

  • 而从工作表区域赋来的数组,无论是1维还是2维,index都从1开始
  • [{}] 这种赋值方式,我认为是偏工作表的,所以index也从1开始
  • 因为 [a1:b5] 就等同于 range("a1;b5")
  • 一般情况下,存储相同类型的多个数据  dim arr1 as variant
  • 也可以存储不同类型的多个数据
  1. Option Explicit
  2. Sub testArr1()
  3. 'Dim arr1() As Integer '这样定义数组是不够的,只定义了是数组,没定义维数和大小,可以试试这样会在赋值时报错
  4. Dim arr1(3) As Integer '定义为integer了,默认至少是0,而不是空
  5. Dim i
  6. arr1(0) = 0
  7. arr1(1) = 1
  8. arr1(2) = 2
  9. 'arr1(3) = "abc" '这样会报类型不匹配
  10. For i = LBound(arr1, 1) To UBound(arr1, 1)
  11. Debug.Print arr1(i)
  12. Next
  13. End Sub
  14. Sub testArr2()
  15. '静态数组,静态在维数不变,长度不变,具体的某个内容可以变化
  16. 'Dim arr2 As Variant '错误写法
  17. Dim arr2(2) As Variant '定义了一个静态数组,且为存储为变量类型
  18. Dim i
  19. arr2(0) = 1
  20. arr2(1) = "a"
  21. For i = LBound(arr2, 1) To UBound(arr2, 1)
  22. Debug.Print arr2(i)
  23. Next
  24. End Sub

 

 

 

4 把数组赋值给其他变量  (变量只是指向数组,但变量不是数组!)

  • 直接给变量赋值一个数组,相当于把变量定义为了数组,比如    dim arr1()   然后  a=arr1() ,也有 b=array(1,2,3)
  • 随便 a=arr1()
  • 变量指向了数组,可以用 a(1)  指向arr1(1) 
  • 但是a 仍然是变量,不是数组,所以不能redim a 
  • 所以我现在这种写法里,虽然没有声明 option explicit ,如果声明了 option explicit 就必须先定义  dim a  或 dim a as variant ,也就是a 是变量,而不是数组。只是数组也可以赋值给变量a
  • 每个变量的类型是,定义时声明的,赋值不改变数据类型,只能改变变量里存储的内容。

 

 

5  给数组赋值

  • 静态数组
  • 可以给静态数组的单个元素赋值改变,但不能给静态数组整体赋值
  • 动态数组
  • 可以给动态数组的单元元素改变赋值,也可以整体改变赋值
  • 但给动态数组单个元素赋值时,需要先声明数组的维数和大小,否则报错
  1. Sub try2()
  2. Dim arr1(5)
  3. Dim arr2()
  4. Dim arr3()
  5. ReDim arr4(2)
  6. arr1(0) = 1
  7. 'arr1 = array(1, 2, 3, 4, 5) '不能给数组赋值,是不能给静态数组赋值?
  8. arr2() = array(1, 2, 3)
  9. 'arr3(0) = 1 '数组使用前,必须先redim 界定清晰(并不就是静态数组, redim arr3(2)虽然是动态的,也是界定清晰的)才可以赋值和使用
  10. ReDim arr3(2)
  11. arr3(0) = 1
  12. End Sub

 

 

二 数组的使用(老文档!)

2.1 数组使用前,必须先定义维数和大小

特别是动态数组,使用前必须先redim() 数组大小后才可以使用

  • 静态数组因为事先声明过了,所以可直接使用
  • 变量可以不事先定义,也可以不赋初值,不同类型的变量,默认初值不同
  • 数组必须实现声明大小后才可以使用,包括运算,或者赋值
  1. Sub test4()
  2. Dim arr1()
  3. ReDim arr1(11) '不redim会报错
  4. j = 1 'j=1也不会出错,但是arr1(0)会为空,不会被赋值
  5. For i = 1 To 11 Step 1
  6. If Not IsEmpty(Cells(i, 1)) Then
  7. arr1(j) = Cells(i, 1)
  8. j = j + 1
  9. End If
  10. Next i
  11. For j = 0 To UBound(arr1())
  12. Cells(j + 1, 9) = arr1(j) '单元格得从1开始,arr()得从0开始
  13. Next j
  14. End Sub

 

2.2 数组的赋值  与  数组项的赋值

静态数组的数组名不能被(整体)赋值,只有 数组的元素,变量,对象可以被赋值

  • 变量,对象,本身是可变的,可以被赋值为数组,也可以赋值为其他内容,其他数组,可以被整体赋值
  • 动态数组,也可以整体赋值,甚至改变维数
  • 静态数组,只能赋值改变其1个元素,不能被整体赋值改变为其他内容
  1. Sub test001()
  2. Dim arr1(3) '如果已经声明为数组名了,arr1就代表arr1(),以后就不能给数组赋值
  3. Dim arr2  As Variant  '相当于dim arr2
  4. Dim arr3 As Object
  5. 'arr1 = Range("a1:c1")     '不能给数组整体赋值? 只能给数组里的元素赋值?arr1 = Range("a1:c1").value 也不行
  6. arr1(0) = Range("a1")      '可以给数组的某个元素赋值
  7. arr2 = Range("a1:c1")      '可以给变量赋值,赋予这个变量整个数组
  8. Set arr3 = Range("a1:c3")  '可以把EXCEL的range 赋值给变量,或对象。然后默认都成为了2维数组。
  9. Range("b2:c2") = 9999
  10. Debug.Print "arr1(0)=" & arr1(0)
  11. Debug.Print "arr2(1,1)=" & arr2(1, 1)
  12. Debug.Print "arr3(1,1)=" & arr3(1, 1)
  13. End Sub

 

  1. Sub test1002()
  2. Dim arr1(10)
  3. Dim arr2()
  4. Dim arr3
  5. '如果先定义为静态数组
  6. arr1(0) = "a" '注意如果写成arr1(0)=a ,赋值内容其实为空,因为变量是a,未赋值。
  7. arr1(1) = 1001
  8. For Each i In arr1
  9. Debug.Print i & " ";
  10. Next
  11. Debug.Print
  12. 'arr1 = Range("a1:a11") '不能给数组赋值,其实就是不能整体赋值
  13. For Each i In arr1
  14. Debug.Print i & " ";
  15. Next
  16. Debug.Print
  17. '如果先定义为动态数组,也很灵活
  18. arr2 = Range("a1:a5")
  19. For Each i In arr2
  20. Debug.Print i & " ";
  21. Next
  22. Debug.Print
  23. arr2 = Range("b1:b7")
  24. For Each i In arr2
  25. Debug.Print i & " ";
  26. Next
  27. Debug.Print
  28. '变量是很灵活的
  29. arr3 = Range("a1:a3")
  30. For Each i In arr3
  31. Debug.Print i & " ";
  32. Next
  33. Debug.Print
  34. arr3 = Range("b1:b5") 'arr3是变量,可以改变维度,大小都行
  35. For Each i In arr3
  36. Debug.Print i & " ";
  37. Next
  38. Debug.Print
  39. End Sub

 

3  数组的范围

3.1 数组的index 下限和上限 :LBound(arr)  和 UBound(arr) ,数组的维数从1开始 lbound(arr1,1 ) 或  lbound(arr) 默认都是第1维

  • 没有第0维得概念,
  • 不要和index可能从0开始搞混!

  

  • 1维下限   lbound(arr,1)   lbound(arr) 

  • 2维下限   lbound(arr,2)

  • 3维下限   lbound(arr,3)

  1. Sub 测试1()
  2. Dim arr1 As Variant
  3. arr1 = Range("a1:c4")
  4. Debug.Print arr1(3, 3)
  5. Debug.Print LBound(arr1)
  6. Debug.Print UBound(arr1)
  7. Debug.Print LBound(arr1, 2) '二维数组,第1维默认是行数,往下数!
  8. Debug.Print UBound(arr1, 2) '二维数组, array(row,column)
  9. Sub 测试2()
  10. Dim arr2()
  11. arr2 = Range("a1:c4")
  12. Debug.Print arr2(3, 3)
  13. Debug.Print LBound(arr2)
  14. Debug.Print UBound(arr2)
  15. Debug.Print LBound(arr2, 2)
  16. Debug.Print UBound(arr2, 2)
  17. End Sub
  18. Sub 测试3()
  19. Dim arr2()
  20. arr2() = Range("a1:c4")
  21. Debug.Print arr2(3, 3)
  22. Debug.Print LBound(arr2)
  23. Debug.Print UBound(arr2)
  24. Debug.Print LBound(arr2, 2)
  25. Debug.Print UBound(arr2, 2)
  26. End Sub
  27. End Sub

 

4 静态数组

4.1 静态数组定义等

  • 静态数组定义的语法:
  • dim arr1(10) as string  ,index是从0开始,包含11个元素
  • dim arr2(5 to 10) as string
  1. Sub t3()
  2. Dim arr(10) As String
  3. For i = 1 To 10 Step 1
  4. arr(i) = i
  5. Debug.Print (arr(i))
  6. Next i
  7. Debug.Print arr(5)
  8. Debug.Print arr(0) '不显示下标越界
  9. Debug.Print arr(11) '会显示下标越界
  10. End Sub

4.2静态数组是不能redim的

  1. Sub t3()
  2. Dim arr5(1 To 5) As Integer
  3. ReDim arr5(1 To 10) As String '不能对静态数组redim改变大小
  4. End Sub

 

5 动态数组

 5.1 动态数组定义 

  1. dim arr1()  或 dim arr3()  as string 
  2. 不定义,直接赋值,比如arr1=range()   或 set arr1=range()
  • 数组重定义:redim
  • 只能重定义动态数组! 也必须重定义大小! 不redim前无法使用
  • redim时,下标可以是变量
  1. Sub t3()
  2. Dim arr3() As Integer '如果定义dim arr3 as integer 会成为一个变量
  3. Dim arr4() As Integer
  4. For i = 1 To 5 Step 1
  5. ReDim arr3(1 To i) '使用数组的内容之前,必须先redim 否则会显示下标越界
  6. ReDim arr4(1 To i)
  7. arr3(i) = i
  8. arr4(i) = i
  9. Debug.Print (arr3(i))
  10. Debug.Print (arr4(i))
  11. Next i
  12. End Sub

 

5.2 只有动态数组才能,也必须redim,静态数组不要redim

  • 静态数组就不要再redim
  • 动态数据就一定需要redim
  1. Sub t4()
  2. Dim arr2()
  3. Rem Dim arr2(5, 6) '使用动态数组 redim就不要和 静态数组定义格式混用
  4. For i = 0 To 5 Step 1
  5. For j = 0 To 6 Step 1
  6. ReDim arr2(0 To i, 0 To j) '动态数组,必须在使用前redim '如果要用静态数组也可以,但不要再redim了!
  7. arr2(i, j) = i + j
  8. Debug.Print arr2(i, j)
  9. Next j
  10. Next i

 

5.3 如果数组赋值时指向EXCEL对象,是二维数组,不能这么使用arr(1),而是arr(i,j)

  • 指向excel对象,比如range() 的 默认为2维数组,因为EXCEL表本身就是二维数组!
  • 二维数组的下标,需要用excel里的r1c1模式
  • 因为是二维数组,不能这么使用,即使只是1行或者1列数,但仍然是二维数据结构!
  • arr1()=range("a1:e1")  虽然看起来只是a1 b1 c1 d1 e1 这5个数,但由于是在excel表里的对象,是二维的 
  1. Sub t3()
  2. Rem Dim arr6 As Integer
  3. arr6 = Range("a1:a5")
  4. Debug.Print arr6(1, 1)
  5. Debug.Print arr6(2, 1)
  6. Debug.Print arr6(3, 1)
  7. Debug.Print arr6(4, 1)
  8. Debug.Print arr6(5, 1)
  9. End Sub

 

6 二维数组

  • dim arr1(4,5) as string
  • dim arr1 (0 to 4,0 to 5) as intege
  1. Sub t4()
  2. Dim arr1(0 To 4, 0 To 5) As Integer
  3. arr1(0, 0) = 999
  4. Debug.Print arr1(0, 0)
  5. End Sub

 

7  定义三维数组

定义静态3维数组

  1. Sub t4()
  2. Dim arr3(3, 4, 5)
  3. arr3(0, 0, 0) = 888
  4. Debug.Print arr3(0, 0, 0)
  5. End Sub

定义动态3维数组

  1. Sub test1001()
  2. Dim arr1()
  3. m = 1
  4. For i = 1 To 3
  5. For j = 1 To 3
  6. For k = 1 To 3
  7. ReDim arr1(i, j, k)
  8. arr1(i, j, k) = m
  9. Debug.Print "arr1(i, j, k)=" & arr1(i, j, k)
  10. m = m + 1
  11. Next
  12. Next
  13. Next

 


  

(0)

相关推荐

  • VBA 临时,关于数组的index : index的初值,index的上下限,index序列

    VBA 临时,关于数组的index : index的初值,index的上下限,index序列

  • Excel VBA学习笔记:VBA如何选取工作簿文件,打开工作簿

    工作中,打开某个工作簿,提取其中数据这样的操作用 VBA 代码如何完成?首先得用VBA控制打开指定的工作簿.下面介绍两种方法. 方式一: GOF = Application.GetOpenFilena ...

  • Excel VBA学习笔记(六):VBA中的循环语句

    介绍四种循环语句的语法: 一.For 循环语法: For 变量=数值 to 数值 Step 步值 "需要执行的语句' Next 变量 Next 后面的"变量名",经常被省 ...

  • EXCEL VBA学习笔记:Collection 集合

    Collection 集合的意思,是一个对象.指用户将一组数据信息,存放于一个"一维数组"中,以便用户随时访问.增添.删除:这样的一个集合体. 集合对象对存放在其中的数据类型,没有 ...

  • Excel VBA学习笔记(一):单元格、单元格区域的表达式

    EXCEL表格中我们要处理的数据都位于单元格中,单元格及单元格区域怎么表示,就是VBA代码的基本了.下面讲解几种常用的单元格.单元格区域语法表达式. 1.[A1] 最简单写法.中括号,里面写上单元格地 ...

  • 缠论学习笔记12:趋势背驰和盘整背驰

    缠师自己总结,缠论分为动力学和形态学两部分.他说,如果按照正常的书去写,肯定是先写形态学,然后再写动力学.但因为他希望先给大家一个简单的概念的东西,所以先写了动力学.缠论的动力学部分,最重要的概念是背 ...

  • 胡希恕伤寒论学习笔记——12

    12.太阳中风,阳浮而阴弱,阳浮者,热自发,阴弱者,汗自出,啬啬(se)恶寒,淅淅恶风,翕翕(xi)发热,鼻鸣干呕者,桂枝汤主之. 桂枝汤方 桂枝三两 芍药三两 甘草二两(炙) 生姜三两(切)大枣十二 ...

  • 圆运动的古中医学(学习笔记1-2)

    本书分上.中.下三篇.上篇以明荣卫病.脏腑病与少阳经病之本体.中篇以尽其蕴.下篇以通其变.所谓本体者,荣卫主表,用汗法治病,脏腑主里,脏用温法,腑用下法治病,少阳经主半表半里,用和法治病是也.凡原文之 ...

  • HALCON 20.11:深度学习笔记(12)

    HALCON 20.11.0.0中,实现了深度学习方法. 本章解释了如何使用基于深度学习的语义分割,包括训练和推理阶段. 通过语义分割,我们使用深度学习(DL)网络将输入图像的每个像素分配到一个类. ...

  • 学习笔记12 | 如何教授方位介词?

    2020年春节前夕,"新型冠状病毒"爆发,线下培训机构被迫停课,更多的孤独症孩子家长将目光投向远程家庭干预. A-IFSP-ASD已经进行了数日,在过去的这段时间里,凭着对孩子的爱 ...