【问题标题】:How to programmatically determine current setting for Option Base in VBA如何以编程方式确定 VBA 中 Option Base 的当前设置
【发布时间】:2019-08-28 22:01:16
【问题描述】:

如何以编程方式确定 VBA 中 Option Base 的当前设置? Option Base 可以设置为01,这决定了数组索引是从0 还是1 开始(参见MSDN)。

但是,我看不到任何简单的方法来找出当前设置是什么。我希望可能有一个 Option() 函数,我可以将参数传递给,例如:

Debug.Print Option("Base")

它会告诉我,但它似乎不存在。

【问题讨论】:

  • 您需要这个有什么理由吗?如果您使用LBoundUBound,则使用哪个设置都没有关系。
  • 您可以定义一个数组并查看LBound0 还是1。但是如果`option base`是由coder决定的,为什么还要找同一个人呢。搜索代码中的Option Base语句即可找到。
  • 拒绝投票者/关闭投票者。如果您留下评论来解释您发现的不清楚的地方,那就太好了。对我来说看起来很清楚。

标签: vba excel


【解决方案1】:

虽然我同意 @jonsharpe 的观点,如果您使用的是 Lbound(arr)Ubound(arr),则无需在运行时知道这一点,但我认为这是一个有趣的问题。

首先,一个正确循环数组的示例。

For i = LBound(arr) To Ubound(arr)
    ' do something
Next

现在,为了完全按照您的要求进行操作,您需要使用VBIDE 库进行访问。也称为“Microsoft Visual Basic for Applications Extensibility”库。它提供对 IDE 和其中代码的访问。您可以使用它来发现是否已声明 Option Base 1。我不建议在运行时尝试这样做。这在开发过程中作为一种静态代码分析会更有用。

首先,您需要add a reference to the librarygrant the code access to itself。完成此操作后,以下代码应该可以执行您想要的操作。

Public Sub FindOptionBase1Declarations()
    
    Dim startLine As Long
    startLine = 1
    
    Dim startCol As Long
    startCol = 1
    
    Dim endLine As Long
    endLine = 1 ' 1 represents the last line of the module
    
    Dim endCol As Long
    endCol = 1 ' like endLine, 1 designates the last Col
    
    Dim module As CodeModule
    Dim component As VBComponent
    For Each component In Application.VBE.ActiveVBProject.VBComponents ' substitute with any VBProject you like
        Set module = component.CodeModule
        
        If module.Find("Option Base 1", startLine, startCol, endLine, endCol, WholeWord:=True, MatchCase:=True, PatternSearch:=False) Then
            
            Debug.Print "Option Base 1 turned on in module " & component.Name
            
            ' variables are passed by ref, so they tell us the exact location of the statement
            Debug.Print "StartLine: " & startLine
            Debug.Print "EndLine: " & endLine
            Debug.Print "StartCol: " & startCol
            Debug.Print "EndCol: " & endCol
            
            ' this also means we have to reset them before we look in the next module
            startLine = 1
            startCol = 1
            endLine = 1
            endCol = 1
        End If
        
    Next 
    
End Sub

请参阅CodeModule.Find documentation 了解更多信息。


如果可以选择使用加载项,@Mat'sMug 和我的开源项目 Rubberduck 有一个 Code Inspection,它将显示整个活动项目中的所有实例。

See this for more information on that particular inspection.

【讨论】:

  • 创建一个数组并检查它的LBound不是更容易吗?
  • 很棒的答案,我希望人们可以轻松地修改它以与其他 Options 一起使用,甚至可能创建我寻求的神圣 Option() 函数。 @jonsharpe 是对的,这是一个有点学术性的问题,但我很高兴你也觉得它很有趣。虽然这是例行公事,但滚动到模块顶部(是的,我知道 Ctrl+Home)毕竟不是一个坏主意。 ;)
  • 是的。当然是@jonrsharpe,但这不是 OP 要求的。
  • @RubberDuck 严格来说,他们要求“找出当前设置的任何简单方法”!但这仍然是一个彻底的答案。
  • 谢谢@jonrsharpe。 VBIDE 是我感兴趣的领域。
【解决方案2】:
Function GetBaseOption() As Long

    Dim arr

    arr = Array("a")
    GetBaseOption = LBound(arr)

End Sub

【讨论】:

  • 不错的解决方案。我想知道您是否可以在即时窗口中成功地一行一行。
  • @RubberDuck 确定只需将其更改为函数并返回LBound 而不是打印它,您可以立即使用它没问题。
  • @RubberDuck - 我不知道会在什么上下文中运行(如果你完全在即时窗口中运行它) - 可能不可靠,因为你可以在每个代码模块中有不同的基本设置。
  • 也许... 值得注意的是 Option Base 处于模块级别,因此此函数将返回它定义的模块的值,而不是从哪里调用它。
  • 大声笑。是的。我落后了。我的想法完全正确。
【解决方案3】:

简单使用:

LBound(Array())

...返回当前的 Option Base 设置。


或者,作为一个函数:

Function optionBase() As Byte
  optionBase = LBound(Array())
End Function

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-01-31
    • 2015-05-12
    • 2011-03-30
    • 1970-01-01
    • 1970-01-01
    • 2014-06-07
    • 1970-01-01
    相关资源
    最近更新 更多