VBA中三种数组变量声明方式的差异及赋值后类型疑问
VBA数组三种声明方式的差异详解
咱们来拆解这三种数组声明的核心区别,以及你提到的单元格区域赋值相关的问题:
一、三种声明方式的本质差异
1. Dim MyArr1 As Variant
- 这是一个变体类型的普通变量,初始状态下它不是数组,只是一个能容纳任何数据类型的“万能容器”——可以存单个数值、字符串,也可以后续转存数组、对象等。
- 灵活性拉满:你先给它赋值
MyArr1 = "Hello"没问题,之后再改成MyArr1 = Array(1,2,3)也完全合法。
2. Dim MyArr2() As Variant
- 这是一个变体类型的动态数组,从声明的那一刻起,它就被锁定为“数组类型”,但还没有分配具体的存储空间(未初始化)。
- 不能直接存单个值:比如
MyArr2 = 123会直接报错,必须通过ReDim手动指定大小,或者用数组/单元格区域赋值来隐式完成初始化(比如MyArr2 = Range("A1:C10").Value是合法的)。
3. Dim MyArr3()
- 在VBA里,这种写法等价于
Dim MyArr3() As Variant——因为声明数组时如果不指定数据类型,默认就是Variant类型。所以它和第二种声明的行为完全一致,只是写法更简洁。
二、是否都是“动态变量”?
得分情况看:
MyArr1 As Variant:它本身不是数组,只是个变体变量。当你给它赋值数组后,这个数组的“动态性”取决于赋值来源:如果是Range.Value生成的,那是固定大小的数组(不能用ReDim调整);如果是Array()函数生成的,就是可以用ReDim调整的动态数组。MyArr2() As Variant和MyArr3():这两个是原生的动态数组,声明时没有固定大小,你可以随时用ReDim修改它的维度和大小,也能通过赋值数组/单元格区域来自动初始化大小。
三、读取单元格区域赋值时的实际影响
你提到的两段代码:
' code1 Dim MyArr: MyArr = Range("a1:c10").Value ' code2 Dim MyArr() As Variant: MyArr = Range("a1:c10").Value
功能上确实没区别,原因是:
- code1里的
Dim MyArr默认就是Variant类型,赋值单元格区域后,它会自动转换成一个二维数组(和单元格区域的行、列对应,注意VBA里这个数组是1起始索引)。 - code2里的动态数组,赋值单元格区域时会自动初始化出对应大小的数组,最终得到的结果和code1完全一致。
如果只是单纯从单元格区域读取值赋值给数组,这三种声明方式(包括Dim MyArr3())最终得到的数组是完全相同的,不会有功能差异。唯一的小区别是:
MyArr1 As Variant可以在赋值数组前后存储其他类型的数据,而另外两种从声明开始就只能是数组类型,不能存单个值。
四、赋值Range.Value时的隐式行为
当执行MyArr = Range("A1:C10").Value时,VBA会隐式创建一个固定大小的二维数组,维度是(1 To 10, 1 To 3)(对应10行3列)。这个数组属于“静态数组”吗?准确来说是“固定大小数组”——你不能用ReDim来修改它的大小,比如执行ReDim MyArr(1 To 5, 1 To 3)会直接报错。
不过有个细节要注意:
- 如果
MyArr是Variant类型(比如code1的情况),你之后可以直接给它重新赋值一个新的数组(比如MyArr = Range("D1:F5").Value),这相当于替换了整个变量的内容,而不是修改原来的数组大小。 - 如果
MyArr是Variant()动态数组(code2的情况),赋值Range.Value后它就变成了固定大小数组,不能再用ReDim调整,但同样可以通过重新赋值新数组来覆盖它。
内容的提问来源于stack exchange,提问作者Przemyslaw Remin
相关产品推荐
相关产品推荐

