VBA中数组的运用
前言
处理量大的数据,还是用数组方便。学习记录备忘
一、Array
1. 数组定义
VBA中数组可以认为是基本类型。
几个基本点:
- 数组分单维、多维
- 定义时指定各维度大小的,为固定数组,定义时不指定的,为可变数组。可变数组用Redim [Preserve] array(大小)来重新定义大小
- 如果不指明,则下标是从0开始的
- 数组存储的值也有类型,如果定义时不指定,则为可变性
'定义单维固定长度数组
Dim arrSD(5) As String
'定义可变数组
Dim arrSD() As String
Redim Preserve arrSD(5,5) '重新定义数组为5*5并且保留已有数据
Redim arrSD(10) '重新定义为单维11个大小的,不保留已有数据
2. VBA对数组支持不是很好?
貌似很多功能(比如排序)都不支持,要曲折实现.
- 将RecordSet数据提取到数组
可以用RecordSet.GetRow(行数) 函数
GetRow()函数返回一个二维数组,注意它的第一维是字段,第二维是记录行。相当于是一个转置的表。代码参考 - 从Range转为数组
从range转为数组非常简单,使用Range.Value属性赋值给数组即可,注意得到的数组下标是从1开始的,不是从0开始的
如下例, Range数据如下
输出结果如下:Sub test() Dim rg As Range, arr() Set rg = Sheets("sheet1").Range("C3:F8") arr = rg.Value Debug.Print UBound(arr, 1) & "x" & UBound(arr, 2) Debug.Print arr(2, 2) End Sub
6x4 Row2 / Col:2
- 把数组值给Range
把数组值给Range时,需要正确地指定Range的大小,数组与range大小不一致时,规律如下:
(1) 对于重合的部分,取数组中的值
(2) 对于 数组比range多出的部分,忽略
(3) 对于数组比range少的部分,补#N/A
如下图所示
注意: 对于一维数组,赋值给Range时要小心。一维数组相当于一行,所以range是多列的行,没问题,但是如果只赋给一列,就会发现只能得到第一个数组元素。这时需要用application.Transpose(array)来先将数组转置然后再赋给range.
- 数组的筛选(Filter)
用Filter函数
其中include参数可以指定结果是包含匹配的结果,还是排除匹配的结果,这个还是比较实用的。
可惜只对一维数组,且只能设单一条件,且只能是字符串
二、ArrayList
实践下来, ArryList非常好用,完全可以取代VBA原生的Array
1. 要添加mscorlib.dll引用才能使用
2. 定义及使用
ArrayList是对象,所以有些特性.
-
定义后需要实例化才能使用。
'定义时直接实例化 Dim arrlistArr_1 As New ArrayList '或者显式实例化 Dim arrlistArr_2 As ArrayList SET arrlistArr_2 = New ArrayList
-
可以做为参数传递给子函数, 在子函数里做的操作会直接反映出来。美妙的是,它甚至都不需要显式指定ByRef 传递。
Sub test() Dim arrFileList As New ArrayList, strErrMsg$ strErrMsg = fun_CheckUnZippedFiles(arrFileList) Set arrFileList = Nothing End Sub ’注意定义函数时,不需要显式指明ArrayList是 ByRef 传递 Function fun_CheckUnZippedFiles(arrFileList As ArrayList) As String Dim arrlistPDF As New ArrayList, arrlistXBRL As New ArrayList ‘..... 处理代码略过 '对象赋值,需要用SET语句 Set arrFileList = arrlistPDF.Clone Set arrlistPDF = Nothing Set arrlistXBRL = Nothing fun_CheckUnZippedFiles = strErrMsg End Function
-
ArrayList涉及的操作(原文参见这里)
Dim arrlistArr_1 As ArrayList, arrlistArr_2 As ArrayList, arr() Dim arr() Set arrlistArr_1 = New ArrayList intLine = 3 For intLine = 3 To 1 STEP -1 arrlistArr_1.Add (CStr(intLine)) Next intLine arrlistArr_1.Sort '排序,顺序 arrlistArr_1.Reverse '没有逆序排序的选项,可以用Reverse曲折实现 SET arrlistArr_2 = arrlistArr_1 'Clone一个Array List arr = arrlistArr_1.ToArray '转换为array
3.ArrayList 多维的处理(待研究)
搞明白了,VBA中的arraylist相当于只有一维的。要实现2维,就是把另一个 arraylist做为元素。这样对普通的应用似乎也不能带来操作上的便利