Excel 如何安全地从VBA项目中删除所有Option Base 1语句

Excel 如何安全地从VBA项目中删除所有Option Base 1语句,excel,vba,Excel,Vba,我正在重构一个包含大约100个模块的VBA项目。一些模块是选项库1,其他模块是选项库0(默认设置)。我希望所有模块都是Option Base 0,因为这样可以简化模块之间的函数移动,从而使它们的位置更加合理 我认为我可以安全地删除项目中的所有Option Base 1语句,如果: 所有设置数组维数的Dim和ReDim语句都有明确的下限 我非常注意Array()函数的使用,因为这将返回一个数组,其下限由它所在模块的选项基决定 还有什么我需要担心的吗?选项库不会影响行计数 请注意,Option Ba

我正在重构一个包含大约100个模块的VBA项目。一些模块是
选项库1
,其他模块是
选项库0
(默认设置)。我希望所有模块都是
Option Base 0
,因为这样可以简化模块之间的函数移动,从而使它们的位置更加合理

我认为我可以安全地删除项目中的所有
Option Base 1
语句,如果:

  • 所有设置数组维数的
    Dim
    ReDim
    语句都有明确的下限

  • 我非常注意
    Array()
    函数的使用,因为这将返回一个数组,其下限由它所在模块的
    选项基决定

  • 还有什么我需要担心的吗?

    选项库不会影响行计数 请注意,
    Option Base
    不会影响行计数,因此不会影响超出范围值的数组,如

    Dim MyArr() As Variant
    MyArr = Range("A1:A10").Value
    
    无论
    选项库是
    1
    还是
    0
    ,都将始终生成一个数组
    MyArr(1到10)

    注意返回数组的函数 您可能还需要注意函数是否返回使用
    array()
    创建的数组或没有显式下限的数组。在这种情况下,您还需要检查父函数/过程数组处理,这可能不是很明显

    如果在不同的模块中使用不同的
    选项库
    ,则这一点尤其棘手

    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
    
    结论
    一般来说,我认为这个方法是安全的,但是你需要有一个强的>体面的< /强>查看你的代码。可能存在一些不明显的陷阱。

    佩赫所写的一切都是正确的,尤其是进行这种更改需要仔细分析

    这是我目前的知识状况:

    代码对更改模块顶部的选项库语句敏感:

    • Dim MyArr(3)
      选项库设置的下限
  • ReDim MyArr(5)
    选项库设置的下限
  • Private MyArr(3)
    选项库设置的下限
  • 公共MyArr(3)
    选项库设置的下限
  • MyArr=Array(1,2,3)
    除非写为
    VBA.Array
    否则
    Array
    函数返回一个数组,其下限由模块的
    选项库设置
  • 代码对更改选项库不敏感

    • Dim MyArr(1到3)
      下限为1
    • ReDim MyArr(0到5)
      下限为0
    • 私有MyArr(0到5)
      下限为0
    • 公共MyArr(0到5)
      下限为0
    • MyArr=VBA.Array(1,2,3)
      下限为0
    • MyArr=Split(“1,2,3”,“,”)
      下限为0
    • MyArr=VBA.Split(“1,2,3”,“,”)
      下限为0。因此,与
      数组
      不同,
      拆分
      的行为是相同的,无论是否以
      VBA作为前缀。
      。它总是返回一个下界为零的数组
    无论模块的
    选项基础是什么,以下语句都是正确的:

    • 索引到
      范围。单元格
      集合从1开始
    • 范围
      (具有多个单元格)的
      .Value
      .Value2
      属性是一个下限为1的二维
      Variant()
      数组

    我不认为还有其他的“陷阱”需要担心,但我想知道是否有。

    补充:
    选项库
    对总是从
    0开始的选项没有影响其余的看起来不错。