我正在重构一个包含大约 100 个模块的 VBA 项目。一些模块是 Option Base 1
,其他模块是 Option Base 0
(默认)。我希望所有模块都是 Option Base 0
,因为这样可以简化模块之间的函数移动,从而使它们的位置更合理。
我认为我可以安全地删除项目中的所有 Option Base 1
语句,如果:
所有设置数组维度的
Dim
和ReDim
语句都有明确的下限。我密切关注
Array()
函数的使用,因为这将返回一个数组,其下限由模块的Option Base
确定它在里面。
还有什么我需要担心的吗?
最佳答案
Option Base 不影响行计数
请注意 Option Base
不影响行计数,因此不影响填充超出范围值的数组,如
Dim MyArr() As Variant
MyArr = Range("A1:A10").Value
将始终生成一个数组 MyArr(1 To 10)
不管Option Base
是1
或 0
.
注意返回数组的函数
您可能还需要注意函数是否返回使用 Array()
创建的数组或者没有明确的下界。在那种情况下,您还需要检查可能不那么明显的父函数/过程数组处理。
如果不同 Option Base
则特别棘手用于不同的模块。
Option Base 1 'if you plan to change this to 0
Function MyArrayReturningFunction() As Variant
MyArrayReturningFunction = Array(1, 2, 3)
End Function
'in another module
Option Base 0 'this was already 0
'so you might assume no changes are needed in this module BUT WRONG!
Sub ParentProcedure()
Dim MyArr As Variant
MyArr = MyArrayReturningFunction
Dim iItem As Long
For iItem = 1 To 3 'You need to take care here even if this module was already Base 0
'because the array was recieved from a Base 1 function.
'Especially in combination with cells (see next paragraph)
Debug.Print MyArr(iItem)
Next iItem
End Sub
数组编号与行编号
此外,如果循环用于数组循环结合单元格和范围,您需要特别注意计数器。
Option Base 1
Sub Test()
Dim MyArr() As Variant
MyArr = Array(1, 2, 3, 4, 5) 'MyArr(1 To 5)
Dim iRow As Long
For iRow = LBound(MyArr) To UBound(MyArr) 'It looks like safe to change because
'LBound/UBound is used BUT see below …
Cells(iRow, A) = MyArr(iRow)
Next iRow
End Sub
需要改成
Option Base 0
Sub Test()
Dim MyArr() As Variant
MyArr = Array(1, 2, 3, 4, 5) 'MyArr(0 To 4)
Dim iRow As Long
For iRow = LBound(MyArr) To UBound(MyArr) 'even if LBound/UBound is already used,
Cells(iRow + 1, A) = MyArr(iRow) 'the counter for the cells needs to be changed,
'but NOT for the MyArr
Next iRow
End Sub
结论
一般来说,我会认为这种方法是安全的,但您需要对您的代码进行体面检查。可能存在不明显的陷阱。
关于excel - 如何安全地从 VBA 项目中删除所有 Option Base 1 语句,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56240768/