9

How can I programmatically determine the current setting for Option Base in VBA? The Option Base can be set to 0 or 1, and this determines whether array indices start at 0 or 1 (see MSDN).

However, I can't see any easy way to find out what the current setting is. I was hoping there might be an Option() function that I could pass a parameter to, something like:

Debug.Print Option("Base")

and it would tell me, but it doesn't seem to be there.

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Caltor
  • 2,538
  • 1
  • 27
  • 55
  • 5
    Is there a reason you need this? If you use `LBound` and `UBound` it doesn't matter which setting is used. – jonrsharpe Apr 01 '15 at 12:33
  • You may define an array and look if `LBound` is `0` or `1`. But if the` option base` is determined by coder, why same person need to find it. Search the `Option Base` statement in the code to find it. – kitap mitap Apr 01 '15 at 12:38
  • Downvoter/Close voter. It would be nice if you left a comment explaining what you find so unclear. Looks pretty clear to me. – RubberDuck Apr 01 '15 at 12:58

3 Answers3

9

While I agree with @jonsharpe that if you're using Lbound(arr) and Ubound(arr), you don't need to know this at runtime, but I think it's an interesting question.

First, an example of properly looping through an array.

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

Now, in order to do exactly what you asked, you'll need to access use the VBIDE library. Otherwise known as the "Microsoft Visual Basic for Applications Extensibility" library. It provides access to the IDE and the code with-in it. You can use it to discover if Option Base 1 has been declared. I don't recommend trying to do it at runtime though. This would be more useful as a kind of static code analysis during development.

First, you'll need to add a reference to the library and grant the code access to itself. Once you've done that, the following code should do what you would like.

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

See the CodeModule.Find documentation for more information.


If using an add-in is an option, @Mat'sMug and I's open source project Rubberduck has a Code Inspection that will show you all instances of this throughout the active project.

Option Base 1 Code Inspection

See this for more information on that particular inspection.

Community
  • 1
  • 1
RubberDuck
  • 11,933
  • 4
  • 50
  • 95
  • 1
    Isn't it easier to just create an array and check its `LBound`? – jonrsharpe Apr 01 '15 at 13:12
  • Awesome answer and I expect one could easily modify this to work with other `Option`s and maybe even create the hallowed Option() function for which I seek. @jonsharpe is right it was a somewhat academic question but I am glad you found it interesting too. It's a beast of a routine though and scrolling to the top of the module (yes I know about Ctrl+Home) doesn't seem like such a bad idea after all. ;) – Caltor Apr 01 '15 at 13:13
  • Yeah. Sure it is @jonrsharpe, but that's not what OP asked. – RubberDuck Apr 01 '15 at 13:14
  • 1
    @RubberDuck strictly, they asked for *"any easy way to find out what the current setting is"*! But this is a thorough answer nonetheless. – jonrsharpe Apr 01 '15 at 13:15
  • Thanks @jonrsharpe. The VBIDE is an area of interest for me. – RubberDuck Apr 01 '15 at 13:17
  • @RubberDuck Thanks. Looks like you actually have a practical application for this. – Caltor Apr 01 '15 at 13:19
  • No @Caltor. It wasn't. I didn't realize the feature was implemented, so I updated my answer. – RubberDuck Apr 01 '15 at 16:35
4
Function GetBaseOption() As Long

    Dim arr

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

End Sub
Tim Williams
  • 154,628
  • 8
  • 97
  • 125
  • Nice solution. I wonder if you could one line this successfully in the immediate window. – RubberDuck Apr 01 '15 at 16:36
  • @RubberDuck sure just change it to a function and return the `LBound` instead of printing it and you can use it in the Immediate no problem. – Brad Apr 01 '15 at 16:38
  • 1
    @RubberDuck - I don't know what context that would run in (if you ran it completely in the Immediate window) - might be unreliable since you can have different Base settings in each code module. – Tim Williams Apr 01 '15 at 16:38
  • Maybe... It's worth noting that Option Base is at the module level, so this function will return the value for the module it's defined in, not where it's called from. – RubberDuck Apr 01 '15 at 16:40
  • Lol. Yes. I'm lagging. My thoughts exactly. – RubberDuck Apr 01 '15 at 16:40
1

Simply use:

LBound(Array())

...to return the current Option Base setting.


Or, as a function:

Function optionBase() As Byte
  optionBase = LBound(Array())
End Function
ashleedawg
  • 20,365
  • 9
  • 72
  • 105