Excel VBA从单元格区域创建数组触发运行时错误9问题咨询
错误原因
首先纠正你的判断:错误9是下标越界错误,不是引用不存在的变量,触发原因和VBA读取单元格区域生成数组的固有规则有关:
- 任何单元格区域直接赋值给Variant变量生成的数组,永远是二维数组:第一维对应区域的行,第二维对应区域的列,且两个维度的下标下界固定为1,不受模块
Option Base设置影响。 - 你参考的示例使用单列区域
A1:A11,生成的数组维度为(1 To 11, 1 To 1):第一维(行)长度为11,第二维(列)长度固定为1。此时UBound(iAmount)默认取第一维上界11,循环中用iAmount(iNum,1)访问的写法刚好匹配数组结构,因此可以正常运行。 - 你修改后的
C23:W23是单行多列区域,生成的数组维度为(1 To 1, 1 To 21):第一维(行)长度固定为1,第二维(列)长度为21。你原有写法的问题在于:- 若完全运行你贴出的代码,
UBound(iAmount)取到的第一维上界是1,循环只会执行1次,仅能读取到C23单元格的值,无法遍历整行所有单元格; - 触发下标越界的核心原因是你实际运行时,要么误将循环上界设为第二维的长度21,导致访问
iAmount(2,1)时第一维索引超出最大有效值1;要么误将二维数组按一维数组逻辑访问(比如直接写iAmount(iNum)省略列索引),最终触发下标越界。
- 若完全运行你贴出的代码,
修复方法
根据使用场景选择对应方案即可:
方案1:按二维数组规则遍历(推荐,兼容性最好)
遍历单行区域时,固定第一维(行)索引为1,遍历第二维(列)即可读取所有值:
Dim iAmount() As Variant Dim iNum As Integer iAmount = Range("C23:W23") ' 遍历单行区域的所有列 For iNum = 1 To UBound(iAmount, 2) Debug.Print iAmount(1, iNum) Next iNum
如果需要兼容任意多行多列的区域,直接使用双层循环分别遍历行、列维度即可:
Dim iAmount() As Variant Dim rowIdx As Integer, colIdx As Integer iAmount = Range("C23:W25") ' 支持任意行列数的连续区域 For rowIdx = 1 To UBound(iAmount, 1) For colIdx = 1 To UBound(iAmount, 2) Debug.Print iAmount(rowIdx, colIdx) Next colIdx Next rowIdx
方案2:转为一维数组后遍历
如果你希望单行/单列区域都统一按一维数组逻辑处理,可以用工作表Transpose函数做转换:
- 单行区域需要转置两次才能得到一维数组
- 单列区域仅需转置一次即可得到一维数组
示例代码:
Dim iAmount As Variant Dim iNum As Integer ' 单行区域转一维数组 iAmount = WorksheetFunction.Transpose(WorksheetFunction.Transpose(Range("C23:W23"))) ' 若为单列区域,用下面这行即可 ' iAmount = WorksheetFunction.Transpose(Range("A1:A11")) For iNum = 1 To UBound(iAmount) Debug.Print iAmount(iNum) Next iNum
内容的提问来源于stack exchange,提问作者JKF
相关产品推荐
相关产品推荐

