打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
【原创】VBA学习笔记(13)VBA的数组 array

一 数组 array

1.1 数据定义

  • 静态数组:长度不变的数组

  • 动态数组:长度不定的数组,需要redim

  • 数组 arr() 必须先声明后才可以使用!

1.2数组的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)

1.3 数组严格定义的重要性

  • Dim arr1(3)

  • Dim arr1( 1 to 3)

  • Option base 1 等等的意义

1.4 创建数组的方法

   创建数组的方法

  • (1) array()

  • (2) split()  (对应join)

  • (3) 挨个元素赋值,甚至循环

  • (4) 变量/对象 = range对象(值)

Sub test101()rem 测试创建数组的各种方法Dim arr1Dim arr2Dim arr3(0 To 3)arr1 = Array(1, 2, 3, 4, 5, 6, 7)arr2 = Split("a,b,c,d,e,f,g", ",")arr3(0) = 1arr3(1) = 2Debug.Print arr1(1)Debug.Print arr2(1)Debug.Print arr3(1)End Sub

二 数组必须声明大小后才可以使用

2.1 测试

  • 变量可以不事先定义,也可以不赋初值

  • 数组必须实现声明大小后才可以使用

  • rem 变量可以赋初值,就可以表达式运算,不同类型的变量,默认初值不同

  • rem 数组必须声明大小后才可以使用,包括运算,或者赋值

2.2 语法差别比较

  • js 里 变量名 $a  字符串a  

  • 和其他语言不同的,其他语言标准 字符,字符串为 "", 变量名不用特殊标记

  • 而js 标记了变量,本质是一样的

  • python里 变量 a 字符串" a” 函数  func()  数组 list=[]

  • 函数和数组形式完全不同,没有实现区分的必要性

  • VBA里  变量 a   字符串 “a”  函数 func()  数组 array()

  • 数组和函数形式很像,所以需要实现定义清楚,否则不好区分

  • 但是VB里,index用 ()  而不是一般语言的 []

Sub t3()Dim arr3(3) As Integerarr4(1) = 1   '直接会报错,arr4未定义!!End Sub

rem 变量可以赋初值,就可以表达式运算,不同的变量,默认初值不同

Sub t3()rem 变量可以赋初值,就可以表达式运算,不同的变量,默认初值不同a = a + 1Debug.Print a'arr4(1) = 1   '直接会报错,arr4未定义!!End Sub
'selectionSub 删除空格4()Dim arr1()ReDim arr1(11)                      '不redim呢j = 0                               'j=1开始就会越界For i = 1 To 11 Step 1   If Not IsEmpty(Cells(i, 1)) Then      arr1(j) = Cells(i, 1)      j = j + 1   End IfNext iFor j = 0 To UBound(arr1())    Cells(j + 1, 9) = arr1(j)      '单元格得从1开始,arr()得从0开始Next jEnd Sub

三 数组的 声明+ 赋值  不同方法 

3.1 声明定义数组有3种方法:

  •  直接声明数组

  • 数组名为变量

  • 数组名为对象名


3.2 数组名(变量名)与数组

  • 变量名代表变量

  • dim a

  • 或者不声明 a 直接使用也默认为变量

  • 数组名 与数组     

  • 如果先声明 dim arr1()

  •    arr1 就代表 arr1()  否则arr1 一般就被认为是变量名

  • 函数名  与函数     

  • 如果先声明的  function func1()

  • func1 就代表 func1()

3.3 数组不能被赋值,只有 数组的元素,变量,对象可以被赋值

  • 而数组不能被直接赋值

  • 只有数组的元素可以被赋值

  • 而变量,对象都是可以被直接赋值的

Sub test001()Rem VBA里的array是数组    Rem 数组不能被赋值,只能给数组的元素赋值Rem Excel里的range是对象,2维数组对象 <> 数组,range是对象不是数组!    Rem 对象是可以被赋值的,赋值给了对象的 range.value属性Dim arr1(3)               '如果已经声明为数组名了,arr1就代表arr1(),以后就不能给数组赋值Dim arr2  As Variant      '相当于dim arr2Dim 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") = 9999Debug.Print "arr1(0)=" & arr1(0)Debug.Print "arr2(1,1)=" & arr2(1, 1)Debug.Print "arr3(1,1)=" & arr3(1, 1)End Sub

四  数组定义和赋值

4.1 数组的 声明/定义大小 和赋值 ----数组使用前需要定义数组大小

  • Dim Array

  • Dim Array()

  • Dim array as object

  • 无差别??--是不是有点太随便了,反而不好学规律

  • 声明数组的时候

  • 无论dim arr1   (as variant)

  • 还是 dim arr1()

  • 但是一旦  dim arr1 as object就有问题,数组不是对象? 报错 缺少数组

  • 但是一旦  dim arr1()  as object就有问题,数组不是对象?  报错缺少数组

总结:这2种没差别

  • dim arr1 或 dim arr1() 都可以

  • arr1=range 或 arr1()=range 都可以

Sub 测试1()Dim arr1 As Variantarr1 = Range("a1:c4")    '这里为什么不 set 为对象呢?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 SubSub 测试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 SubEnd Sub

4.2 array() 函数的作用----再升高一维数组

Sub 测试1()Dim arr1   '定义arr1() 其实arr1就代表了数组把  arr1()只是明晰了声明了arr1是数组arr1 = Array(Range("a1:a4"), Range("b1:b4"), Range("c1:c4"))Rem array()转的都是1维数组把, no 这里是三维数组Rem array 只是加一维,并非是转成1维数组了Debug.Print arr1(0)(1)(1)For i = 1 To UBound(arr1)Debug.Print arr1(i)(2)(1) '写成arr(i)会报类型不匹配,因为数组维数不对Next iEnd Sub

4.3 关于dim array() 的index下标

  • array 使用前,必须先定义 dim array() 大小

  • 无论是静态的数组,或是静态的大小  dim array(10) 或  redim  array()

  • 首先要记住,cells()等是excel对象,其pos是(row column)组成,所以下标必须从1开始,不能从开始

  • 而array() 默认index都是从0开始, 比如这么定义 dim arr1(4,3) 实际上是 arr1(0 to 4, 0 to 3)

  • 但是array的index下标可以从1 或者2 等其他开始

  • 比如 dim array1(1 to 5)  dim array2(2to7)

  • 一般为了两者匹配,所以定义数组维度时会这么定义

  •  arr1(1 to 4, 1 to 3)  完全是为了方便和excel对象的数据匹配

  • 所以下面两种写法都可以,如果用array的index从0开始则需要注意,对应匹配好excel对象的 下标+1 和ubound -1

Sub 测试2()Dim arr1(4, 3)For i = 0 To 3For j = 0 To 2arr1(i, j) = Cells(i + 1, j + 1)Debug.Print arr1(i, j)Next jNext iDebug.Print vbCrLf    ‘测试脚手架,不是一直有Debug.Print arr1(0, 0)End Sub
  • 下面这么严格和excel对应也是OK的,一般人会这么写,

  • 但要明白 array() 不严格声明下标 1 to 4 默认都会是 0 to 4,要明白这个!!

  • 但是因为没有arr1(0,0) 所以Debug.Print arr1(0, 0) 会报错!

Sub 测试3()Dim arr1(1 To 4, 1 To 3)For i = 1 To 4For j = 1 To 3arr1(i, j) = Cells(i, j)Debug.Print arr1(i, j)Next jNext iDebug.Print vbCrLfEnd Sub
  • 但是如果含糊写,又不对应,也没问题

  • 只是要知道。Arr1(0,0) 这里实际是没被赋值的,只是VBA这里没事。

  • Debug.Print arr1(0, 0)  不会打印出东西 none 也不报错

Sub 测试4()Dim arr1(4, 3)For i = 1 To 4For j = 1 To 3arr1(i, j) = Cells(i, j)Debug.Print arr1(i, j)Next jNext iEnd Sub

五  数组分类

5.1 静态数组

  • 静态数组定义的语法:

  • dim arr1(10) as string     资料说是从1开始,我测试是从0开始

  • 但是0~10都不越界,不是有11个数了? 就是0-11?

  • dim arr2(5 to 10) as string

  • 另外,数组数据类型也并不需要都是 as string, 测试 as integer同样没问题

Sub t3()Dim arr(10) As StringFor i = 1 To 10 Step 1arr(i) = iDebug.Print (arr(i))Next iDebug.Print arr(5)Debug.Print arr(0)   '不显示下标越界Debug.Print arr(11)  '会显示下标越界End Sub
Sub t3()Dim arr(10) As IntegerFor i = 1 To 10 Step 1arr(i) = iDebug.Print (arr(i))Next iDebug.Print arr(5)Debug.Print arr(0)   '不显示下标越界End Sub

 

5.2 动态数组

  • 动态数组定义

  • dim arr3()  as string   或 dim arr3()

  • 数组重定义:redim

  • 只能重定义动态数组! 也必须重定义大小! 不redim前无法使用

  • redim时,下标可以是变量

Sub t3()Dim arr3() As Integer  '如果定义dim arr3 as integer 会成为一个变量Dim arr4() As IntegerFor i = 1 To 5 Step 1ReDim arr3(1 To i)  '使用数组的内容之前,必须先redim 否则会显示下标越界ReDim arr4(1 To i)arr3(i) = iarr4(i) = iDebug.Print (arr3(i))Debug.Print (arr4(i))Next iEnd Sub
Sub t3()Dim arr5(1 To 5) As IntegerReDim arr5(1 To 10) As String   '不能对静态数组redim改变大小End Sub

5.3 定义数组指向EXCEL对象,是二维数组,不能这么使用arr(1)

  • 指向excel对象,比如range() 的 默认为2维数组,因为EXCEL表本身就是二维数组!

  • 二维数组的下标,需要用excel里的r1c1模式

  • 因为是二维数组,不能这么使用,即使只是1行或者1列数,但仍然是二维数据结构!

  • arr1()=range("a1:e1")  虽然看起来只是a1 b1 c1 d1 e1 这5个数,但由于是在excel表里的对象,是二维的 

Sub t3()Rem Dim arr6 As Integerarr6 = 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

 

六 定义二维数组

6.1 定义

  • 定义方法

  • dim arr1(4,5) as string

  • dim arr1 (0 to 4,0 to 5) as integer

Sub t4()Dim arr1(0 To 4, 0 To 5) As Integerarr1(0, 0) = 999Debug.Print arr1(0, 0)End Sub

6.2 动态数组和静态数据的语法不要混用!

  • 静态数组就不要再redim

  • 动态数据就一定需要redim

Sub t4()Dim arr2()Rem Dim arr2(5, 6)  '使用动态数组 redim就不要和 静态数组定义格式混用For i = 0 To 5 Step 1For j = 0 To 6 Step 1ReDim arr2(0 To i, 0 To j)  '动态数组,必须在使用前redimarr2(i, j) = i + jDebug.Print arr2(i, j)Next jNext i
Sub t4()Dim arr2(5, 6)For i = 0 To 5 Step 1For j = 0 To 6 Step 1Rem ReDim arr2(0 To i, 0 To j) '如果要用静态数组也可以,但不要再redim了!arr2(i, j) = i + jDebug.Print arr2(i, j)Next jNext iEnd Sub

七 定义三维数组

  • 下标也是从0开始的

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

 

多维数组的问题---3维数组的表达方式???

  • 到底哪种指定维度的方法正确?

  • arr(1,2)

  • arr(1)(2)

  • 现在实际测试的结果是

  • arr可以定位为变量,赋值为一个range 或 range.value,等价

  • 但是没有 array().value 这种用法

  • 现在实际测试的结果是

  • 2维数组,只能arr(1,2)

  • 3维数组,有的arr(1,2,3) 有的arr(1)(2)(3)

三维数组的表示问题,和之前的不同了Sub test_3d()Dim arr1(1 To 2)Dim arr2(1 To 2, 1 To 2)Dim arr3(1 To 2, 1 To 2, 1 To 2)Dim arr4arr1(1) = 1arr2(1, 1) = 10arr3(1, 1, 1) = 100'arr4(1)(1)(1) = 100  为啥现在这么写不行了?莫不是偏移3次?对比之前的Debug.Print arr1(1)Debug.Print arr2(1, 1)Debug.Print arr3(1, 1, 1)'Debug.Print arr4(1)(1)(1)End Sub
Sub test1()Dim arr1Dim arr2Dim arr3Dim arr4Dim arr5(3, 4, 5)arr1 = Range("b1:b3")Debug.Print arr1(3, 1)'Debug.Print arr1(3)(1)arr2 = Range("b1:b3").ValueDebug.Print arr2(3, 1)'Debug.Print arr2(3)(1)arr3 = Array(Range("a1:a3"), Range("b1:b3"))'Debug.Print arr3(0, 1, 1)Debug.Print arr3(1)(1)(3)'arr4 = Array(Range("a1:a3"), Range("b1:b3")).Value   '报错''Debug.Print arr4(0, 1, 1)'Debug.Print arr4(1)(1)(3)arr5(0, 0, 0) = 111Debug.Print arr5(0, 0, 0)'Debug.Print arr5(0)(0)(0)End Sub
本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
【原创】VBA学习笔记(12)VBA的数组 array
Vba遍历数组
【VBA初学者教程】- 第一章 VBA入门知识:在Visual Basic中使用Excel工作表函数...
VBA 临时,关于数组的index : index的初值,index的上下限,index序列
VBA数组基础学习
面向VBA一维数组的实用自定义函数
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服