1 数组的不同定义方式,会导致 index的起点不同
总结,简单的说,就是VBA里的数值,index默认从0 开始,而从工作表来源的函数,默认index从1开始
- 用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")
Sub test18a()
Dim arr1, arr2, arr3, arr4, arr5
'一维数组
'数组的多种定义和index初值
'总结,用VBA的数值array() 或者 dim 或者 redim 这几种方法,默认index从0开始
'当然 dim 或者 redim 可以声明从1开始或从其他开始
'[{}] 这种赋值方式,我认为是偏工作表的,
'因为 [a1:b5] 就等同于 range("a1;b5")
' 而从工作表区域赋来的数组,无论是1维还是2维,index都从1开始
arr1 = Array(1, 2, 3, 4, 5)
arr2 = [{6,7,8,9,10}]
arr3 = Application.WorksheetFunction.Transpose(Range("a1:a5"))
arr4 = WorksheetFunction.Transpose(Range("c1:g1"))
arr5 = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Range("c1:g1")))
ReDim arr6(4)
For i = 0 To 4
arr6(i) = i
Next
Debug.Print "arr1的index从小到大为" & LBound(arr1, 1) & " " & UBound(arr1, 1)
Debug.Print "arr2的index从小到大为" & LBound(arr2, 1) & " " & UBound(arr2, 1)
Debug.Print "arr3的index从小到大为" & LBound(arr3, 1) & " " & UBound(arr3, 1)
Debug.Print "arr4的index从小到大为" & LBound(arr4, 1) & " " & UBound(arr4, 1)
Debug.Print "arr5的index从小到大为" & LBound(arr5, 1) & " " & UBound(arr5, 1)
Debug.Print "arr6的index从小到大为" & LBound(arr6, 1) & " " & UBound(arr6, 1)
End Sub
2 获得array的内容:arr1(index) 和 for循环
- 获得单个元素
- 基本思路就是 arr1(index)
- 使用类这样的语句即可 arr1(1)=1 或 arr1(1,2)
- 获得所有元素
- 遍历法1:for each in 可以无视几维数组
- 遍历法2:for i =lbound(arr,1) to ubound(arr1,1) 需要先理解数组的维数等 数组结构
Sub test18b()
arr1 = Array(1, 2, 3, 4, 5)
arr2 = [{6,7,8,9,10}]
arr3 = Application.WorksheetFunction.Transpose(Range("a1:a5")) '表现为1行,可认为是1维数组
arr4 = WorksheetFunction.Transpose(Range("c1:g1")) '表现为1列默认为2维数组
arr5 = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Range("c1:g1"))) '表现为1行,可认为是1维数组
ReDim arr6(4)
For i = 0 To 4
arr6(i) = i
Next
Debug.Print "取数组中的单个值"
Debug.Print arr1(1)
Debug.Print arr2(1)
Debug.Print arr3(1)
Debug.Print arr4(1, 1)
Debug.Print arr5(1)
Debug.Print arr6(1)
Debug.Print "遍历数组中的所有值"
For Each i In arr1
Debug.Print i;
Next
Debug.Print
For Each i In arr4
Debug.Print i;
Next
Debug.Print
For i = LBound(arr4, 1) To UBound(arr4, 1)
Debug.Print "arr4(" & i & ")=" & arr4(i, 1) & " ";
Next
Debug.Print
End Sub
3 如何取出数组的index呢?
获得数组的内容是常规操作,但是获得 数组的index 却不像获得字典的key 那样直接
基本思路
3.1 方法1: 利用 lbound() 和ubound() + index必须是连续的整数特性 取得index序列,也可以取得 index 个数。
- 利用 lbound() + ubound() + index必须是连续的整数特性 取得index序列
- 数组的个数 =数组的index个数= ubound() - lbound() +1
Sub test17a()
arr1 = Array(1, 2, 5)
arr2 = [{1,2,5;7,8,9}]
Debug.Print "方法1,lbound 和 ubound + index 的连续性"
Debug.Print "可以取多维数组,任何一维的index"
a = LBound(arr1, 1)
b = UBound(arr1, 1)
For i = a To b
Debug.Print i;
Next
Debug.Print
Debug.Print "arr1的index个数" & b - a + 1
Debug.Print
For i = LBound(arr2, 1) To UBound(arr2, 1)
Debug.Print i;
Next
Debug.Print
Debug.Print "arr2的第1维的index个数" & UBound(arr2, 1) - LBound(arr2, 1) + 1
Debug.Print
For i = LBound(arr2, 2) To UBound(arr2, 2)
Debug.Print i;
Next
Debug.Print
Debug.Print "arr2的第2维的index个数" & UBound(arr2, 2) - LBound(arr2, 2) + 1
Debug.Print
End Sub
3.2 方法2: 在遍历数组的过程中计数,即是index 相同的映射(count计数起点需要是lbound,否则不一定是index序列)
- 可能出问题的地方: 很可能count序列,只是 index 序列的一个映射而已。
- 虽然可以保证 计数数量是对的
- 但是不能保证 数组的 index 起点 lbound(arr) 是多少
- 必须让count1起点是 lbound(arr) 才能保证计数 == index (下面例子的第2个刚好是 count2计数从1开始,数组index(lbound)也从1开始)
Sub test17b()
arr1 = Array(1, 2, 5)
arr2 = [{1,2,5;7,8,9}]
Debug.Print "1维数组"
Count1 = 0
For Each i In arr1
Count1 = Count1 + 1
Debug.Print "index为 " & Count1;
Debug.Print " 的元素= " & i
Next
Debug.Print
Debug.Print "2维数组"
Count2 = 0
For i = LBound(arr2, 1) To UBound(arr2, 1)
For j = LBound(arr2, 2) To UBound(arr2, 2)
Count2 = Count2 + 1
Debug.Print "index为 " & Count2;
Debug.Print " 的元素= " & arr2(i, j)
Next
Debug.Print
Next
Debug.Print
End Sub
3.3 方法3:遍历数组元素时,用 worksheetfunction.match() 反查(如果元素不唯一,可能差不到正确index)
- 局限性:
- 如果数组的元素有重复的,查到的index 不唯一
- match()函数有报错跳出的可能,要预先考虑处理
Sub tet17c()
arr1 = Array(1, 2, 5)
For Each i In arr1
Debug.Print WorksheetFunction.Match(i, arr1, 0);
Next
End Sub