前面我们已经介绍了一维及多维数组,也讨论了静态和动态数组。今天我们介绍几个关于数组的函数。VBA 中有一个 Array() 函数,这个函数返回一个数组,数组的元素就是这个函数的参数。Dim MyA() As VariantMyA = Array("Hello", "你好!", 3.5, Date(), True, 3192)Debug.Print LBound(MyA) & ", " & UBound(MyA)Debug.Print TypeName(MyA)Debug.Print VarType(MyA)
首先声明 MyA 是一个 Variant 类型的动态数组,然后使用 Array() 构造一个数组返回给 MyA。第 5 行的结果是 0, 5,说明 MyA 的下界是 0,上界是 5,共有 6 个元素,这 6 个元素都是变体(Variant)类型。第 6 行的结果是 Variant(),说明 MyA 是一个变体类型的数组。第 7 行的结果是 8204,因为 8204 = 8192 + 12,8192 是 vbArray 的类型代码,12 是 vbVariant 的类型代码,所以 8204 就表示一个元素类型是 Variant 的数组。Dim MyA() As VariantMyA = Array()Debug.Print LBound(MyA) & ", " & UBound(MyA)
这个例子使用 Array() 函数构造了一个空数组,第 4 行的结果是 0, -1。为什么 UBound(MyA) 的结果会是 -1 呢?这是因为:虽然此时 MyA 是一个空数组,但 TypeName(MyA) 和 VarType(MyA) 返回的结果和上面是一样的,这说明它们是同样类型的数组。其中,arraylist 是一个由逗号分隔的数组列表,也就是说,Erase 可以一次性抹除多个数组。针对静态数组还是动态数组,Erase 的动作也不一样。见下面的例子。Dim MyNumArray(10) As IntegerDim MyStrArray(10) As StringDim MyFixedStrArr(10) As String*30Dim MyVarArr(10) As VariantDim MyDynArr() As VariantRedim MyDynArr(10)Erase MyNumArr ' 所有元素置为 0Erase MyStrArr ' 所有元素置为空字符串Erase MyFixedStrArr ' 所有元素置为 0Erase MyVarArr ' 所有元素置为 EmptyErase MyDynArr ' 释放由 ReDim 分配的数组空间
由这个例子可以看出,对于静态数组,Erase 的作用是抹除各元素原来的值,相当于对数组作初始化,并不改变数组的大小。但对于动态数组,则是释放由 ReDim 分配的数组空间,此时,虽然该数组(MyDynArr)的 TypeName 仍然是 Variant(),但已经没有了数组的特征,譬如 LBound 和 UBound 函数都不能再使用,除非再次使用 ReDim 分配数组空间。Join() 函数将数组元素连接为一个字符串,其一般形式为:Join(sourcearray[, delimiter])
delimiter 参数的作用是提供连接字符串的分隔符,如果不提供 delimiter 参数,则字符串之间由空格分隔,如果 delimiter 是空字符串,则字符串之间没有分隔符。Dim MyA(2) As StringDim Names As StringMyA(0) = "张三"MyA(1) = "李四"MyA(2) = "王五"Names = Join(MyA, ",")Debug.Print Names ' 张三,李四,王五
例2. 用 Join 连接 Variant 类型的数组元素Dim MyA() As VariantMyA = Array("Hello", "你好!", 3.5, Date, True, 3192)Debug.Print Join(MyA, "|")
这个例子的输出结果是:Hello|你好!|3.5|4/8/2026|True|3192与 Join() 相反,Split() 函数将一个字符串按照指定的分隔符分割为数组。Dim Greeting As StringDim MyA() As StringGreeting = "Hello, nice to meet you."MyA = Split(Greeting)
在这个例子中,没有为 Split 指定分隔符参数,则使用默认的空格分隔符。执行完第 5 行语句之后,MyA(0) 的内容为 Hello,,MyA(1) 的内容为 nice,MyA(4) 的内容为 you.。Split(expression[, delimiter[, limit[, compare]]])
从这个一般形式可以看出,在使用 Split 函数时必须要指定 expression 参数,这个就是要分割的字符串表达式,其他参数都是可选的:- delimiter:指定分割字符串时的分隔符,如果不指定 delimiter,则使用默认的空格作为分隔符
- limit:参数限定返回的数组元素数,-1 表示返回所有被分割的子字符串
- compare:指定在比较分隔符时是否区分大小写,compare 的值如下:
- vbUseCompareOption:-1,表示使用 Option Compare 的设置
- vbBinaryCompare:0,执行二进制比较,即区分大小写
- vbTextCompare:1,执行文本比较,即不区分大小写
- vbDatabaseCompare:2,只用于 Access,此处不讨论
这个例子演示了 Split 和 Join 的组合作用,将一个单行的地址字符串分割为由换行符分隔的多行地址字符串。这个例子同时也演示了 limit 参数的作用:省略 limit 参数时,Split 返回所有的子字符串,如果指定 limit 参数为 3,则只返回 3 个子字符串,最后的字符串 Indiana, 46204 不再分割,作为一个子字符串返回。在指定 compare 参数为 vbBinaryCompare 时,在比较分隔符时区分大小写,因此只将 hello 作为分隔符,而忽略了 Hello。而在指定 vbTextCompare 时,因为此时不区分大小写,因此 Hello 也作为了分隔符。