Option Base 0 or Option Base 1?

What is your preference?


  • Total voters
    2
I tend to use option base 0, but, where appropriate, just not use element (0) :)
 

Excel Facts

Save Often
If you start asking yourself if now is a good time to save your Excel workbook, the answer is Yes
And sometimes it's difficult to use 1-based:

<font face=Courier New><SPAN style="color:darkblue">Option</SPAN> <SPAN style="color:darkblue">Base</SPAN> 1

<SPAN style="color:darkblue">Sub</SPAN> TestArr()
<SPAN style="color:darkblue">Dim</SPAN> myArr1 <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>, myArr2 <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>
<SPAN style="color:darkblue">Dim</SPAN> MyArr3 <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>, myArr4 <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>
<SPAN style="color:darkblue">Dim</SPAN> myArr5() <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Byte</SPAN>, myArr6 <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>
<SPAN style="color:darkblue">Let</SPAN> myArr1 = Array(1, 2, 3)
<SPAN style="color:darkblue">Let</SPAN> myArr2 = [{1,2,3}]
<SPAN style="color:darkblue">Let</SPAN> MyArr3 = [transpose(transpose(a1:c1))]
<SPAN style="color:darkblue">Let</SPAN> myArr4 = [transpose(a1:a3)]
<SPAN style="color:darkblue">Let</SPAN> myArr5 = StrConv("1,2,3", vbFromUnicode)
<SPAN style="color:darkblue">Let</SPAN> myArr6 = Split("1|2|3", "|")
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr1)
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr2)
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(MyArr3)
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr4)
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr5)
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr6)
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN></FONT>

One reason to not even bother mucking with the declaration, simply use LBound.

XLD said:
There shouldn´t be a need to check the LBound for arrays if we know the basic about arrays in XL.
There are so many ways to stack an array with VBA, and the results vary to such an extent that LBound & UBound are tremendous tools!

I can certainly see a need to check the boundaries and it's hard to see why there would be any shame in using them, besides, like Colt 45, they work every time (including the previous example)! :biggrin: (y)
 
Like Dennis I prefer to explicitly declare LBound & UBound so anyone else reading the code is clear what the bounds are for the array.
Dim MyArray(1 to 5)

My understanding is when you assign a range directly to an array the range LBound is based upon whats in Option Base so the default is zero unless Option Base is declared otherwise. However, you can Redim to get around this, settle for Base 0 or use LBound if its a dynamic array.

Sub ThisWorks()
Dim Arr()
ReDim Arr(1 To 3)
Arr = Range("a1:c1")
[a2:c2] = Arr
End Sub

Sub ThisDoesnt()
Dim Arr(1 To 3)
Arr = Range("a1:c1")
[a2:c2] = Arr
End Sub

Some people use Option Base 1 alot but I dont like to rely on this at all if I can help it. Your procedure should preferably be self contained in my opinion unless its unavoidable as many people (including me) often miss seeing that Option Base 1 is set so wonder why the code fails. Especially people who dont understand the code and just paste it into their module.
 
Parry said:
My understanding is when you assign a range directly to an array the range LBound is based upon whats in Option Base so the default is zero unless Option Base is declared otherwise.
Nope, this is the opposite of what Dennis has said, which is correct with respect to population via Range Object coercion (i.e., it's 1), e.g.,

<font face=Courier New><SPAN style="color:darkblue">Option</SPAN> <SPAN style="color:darkblue">Base</SPAN> 0

<SPAN style="color:darkblue">Sub</SPAN> ThisWorks()
<SPAN style="color:darkblue">Dim</SPAN> Arr() <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>
Arr = Range("a1:c1")
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(Arr)
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN>
</FONT>
 
NateO said:
Parry said:
My understanding is when you assign a range directly to an array the range LBound is based upon whats in Option Base so the default is zero unless Option Base is declared otherwise.
Nope, this is the opposite of what Dennis has said, which is correct with respect to population via Range Object coercion (i.e., it's 1), e.g.,

<font face=Courier New><SPAN style="color:darkblue">Option</SPAN> <SPAN style="color:darkblue">Base</SPAN> 0

<SPAN style="color:darkblue">Sub</SPAN> ThisWorks()
<SPAN style="color:darkblue">Dim</SPAN> Arr() <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>
Arr = Range("a1:c1")
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(Arr)
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN>
</FONT>

I think you have just misunderstood me Nate & I dont believe this is the opposite at all. You certainly have more experience in this so I will bow to your knowledge. In your example LBound was 0 - just as I said because Option Base is 0 whether declared as 0 explicitly or omitted. I am saying if Option Base is 1 then the range is LBound 1, if its Option Base 0 the range is LBound 0 unless I redim the array to amend the bounds. If you are disagreeing then you are saying Option Base 1 will have no effect and the array will be LBound 0? :biggrin:

Option Base 1

Sub AreYouSureNate()
Dim Arr() As Variant
Arr = Range("a1:c1")
Debug.Print LBound(Arr)
End Sub
 
Just to show that we don´t always need to use the LBound (or Ubound) below is a sample where we use pointers to read the memory to get the number of dimensions an array has.

Code:
Option Explicit

Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (dest As _
    Any, source As Any, ByVal bytes As Long)

Function Count_Array_Dimensions(arr As Variant) As Long
Dim ptr As Long
Dim VType As Integer
    
Const VT_BYREF = &H4000&
    
CopyMemory VType, arr, 2
    
If (VType And vbArray) = 0 Then Exit Function
    
CopyMemory ptr, ByVal VarPtr(arr) + 8, 4
    
If (VType And VT_BYREF) Then
    CopyMemory ptr, ByVal ptr, 4
End If

If ptr Then
    CopyMemory Count_Array_Dimensions, ByVal ptr, 2
End If
End Function

Sub Check_Dimensions()
Dim stArray(1 To 4, 1 To 4, 1 To 4, 1 To 4)
Dim rnData As Range
Dim vaArray As Variant

Dim lnNumberofDim As Long

lnNumberofDim = Count_Array_Dimensions(stArray)

Debug.Print lnNumberofDim

With ActiveSheet
    Set rnData = .UsedRange
End With

vaArray = rnData.Value

lnNumberofDim = Count_Array_Dimensions(vaArray)

Debug.Print lnNumberofDim

End Sub

The point is that we don't need to mess around with the LBound. As for the Ubound I believe it is more useful then the LBound-function. But not by reduce it / add 1 to it.

And again, don't try to apply it in real life as this is not the case.

Comments are welcome but don´t expect me to get back to this thread again.


parry - go back to the first message I posted and take another look into it.

Kind regards,
Dennis
 
Hello Parry,

Well, I thought I knew what you were saying, but I'm far less confident about that at this point. Here's what Dennis was saying that I concur with:

When you coerce a Range Object to an array the lower boundary is 1. It doesn't matter if you use:

1) Option Base 0
2) Option Base 1
3) Option Base Fruity Pebbles
4) ReDim(Whatever you want to make up)

E.g.,

<font face=Courier New><SPAN style="color:darkblue">Option</SPAN> <SPAN style="color:darkblue">Base</SPAN> 0
<SPAN style="color:green">'Non-Factor</SPAN>

<SPAN style="color:darkblue">Sub</SPAN> NateIsFairlyCertain()
<SPAN style="color:darkblue">Dim</SPAN> Arr() <SPAN style="color:darkblue">As</SPAN> <SPAN style="color:darkblue">Variant</SPAN>

<SPAN style="color:green">'Not even the folling matters:</SPAN>
<SPAN style="color:darkblue">ReDim</SPAN> Arr(5461 <SPAN style="color:darkblue">To</SPAN> 32768, 0 <SPAN style="color:darkblue">To</SPAN> 7)

Arr = Range("a1:c1")
<SPAN style="color:green">'Just a fox in the hen house has chicken for supper _
    every time, your immediate window will show 1 _
    on the lower boundary with this type of array _
    stack every time.</SPAN>
<SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(Arr, 1); <SPAN style="color:darkblue">UBound</SPAN>(Arr, 1); _
    <SPAN style="color:darkblue">LBound</SPAN>(Arr, 2); <SPAN style="color:darkblue">UBound</SPAN>(Arr, 2)
<SPAN style="color:darkblue">End</SPAN> <SPAN style="color:darkblue">Sub</SPAN>
</FONT>

If this is consistent with what you're saying, then I agree, if not, then I don't. :biggrin:

Edit: Tab spacing got bolloxed up!
 
XLD said:
Just to show that we don´t always need to use the LBound (or Ubound) below is a sample where we use pointers to read the memory to get the number of dimensions an array has.
The number of dimensions does not correlate with the boundaries of any dimension. These are two different, independent aspects of an array.

You can memorize that Split() returns a 0-based array and a Range Object coerces to a 1-based array, yadda, yadda, yadda, but for me, life's too short. I'll use LBound().

Go back to my post with the 6 arrays and flip the base setting, you'll see it only impacts 1/6, and they're not consistent with each other!

It'll be easier to compare if you substitute all of the debug prints with the following single call:

<font face=Courier New><SPAN style="color:darkblue">Debug</SPAN>.<SPAN style="color:darkblue">Print</SPAN> <SPAN style="color:darkblue">LBound</SPAN>(myArr1); <SPAN style="color:darkblue">LBound</SPAN>(myArr2); <SPAN style="color:darkblue">LBound</SPAN>(MyArr3); <SPAN style="color:darkblue">LBound</SPAN>(myArr4); _
    <SPAN style="color:darkblue">LBound</SPAN>(myArr5); <SPAN style="color:darkblue">LBound</SPAN>(myArr6)</FONT>
 
I like to challenge ideas to ensure better understanding but Im not sure Im 100% clear on this but I wont monopolize this thread anymore. Im surprised of the result in your code Nate and I will have to think about yours Dennis to understand it.

I guess you are very sure then Nate. :LOL:
I acquiesce to you guys superior knowledge. (y)

Sub DamnImWrong()
Dim Answer As MrExcelPost

If Answer = Dennis or Answer = Nate Then
(y)
End If
End Sub
 

Forum statistics

Threads
1,214,826
Messages
6,121,794
Members
449,048
Latest member
greyangel23

We've detected that you are using an adblocker.

We have a great community of people providing Excel help here, but the hosting costs are enormous. You can help keep this site running by allowing ads on MrExcel.com.
Allow Ads at MrExcel

Which adblocker are you using?

Disable AdBlock

Follow these easy steps to disable AdBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the icon in the browser’s toolbar.
2)Click on the "Pause on this site" option.
Go back

Disable AdBlock Plus

Follow these easy steps to disable AdBlock Plus

1)Click on the icon in the browser’s toolbar.
2)Click on the toggle to disable it for "mrexcel.com".
Go back

Disable uBlock Origin

Follow these easy steps to disable uBlock Origin

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back

Disable uBlock

Follow these easy steps to disable uBlock

1)Click on the icon in the browser’s toolbar.
2)Click on the "Power" button.
3)Click on the "Refresh" button.
Go back
Back
Top