VBA で Option Base 1 なる記述ができますが、なぜこれを使おうと思うのか理解に苦しみます。なお、反論は聞きません。が、どうしても何か言いたいことがあればコメントどーぞ。
スポンサーリンク
Option Base 1 とは
VBA では、配列のインデックスは、デフォルトでは 0 始まりです。しかし、Option Base 1 なる記述を書けば、配列のインデックスは 1 始まりとすることができます。
おそらく、エクセルのセルなどを扱う場合に、行や列を1始まりとして実装しているものもあります。おそらくは、その実装に合わせて、配列のインデックスも1始まりとした方が分かりやすいと考える人もいるだろうとの考えから、本オプションがあるのだと勝手に想像します。
ただし、そうであろうがなかろうが関係ありません。どうでも良いことです。
Option Base 1 のサンプルスクリプト
次のように、Option Base 1 を記述している状態で配列を定義した場合には、配列インデックスは1始まりとなるので、0をインデックスに指定すると実行時エラーとなります。コンパイルエラーにはなりません。
Option Explicit Option Base 1 Private Sub Workbook_Open() ' 配列を宣言 Dim arrays(5) As String arrays(0) = 1 ' 実行時エラー arrays(1) = 1 ' OK End Sub
さらに困ったことに Option Base 1 を指定していても、Split関数は0始まりの配列を返します。そうです、Option Base は Split関数には影響を与えません。
仮に影響を与えることができる記述があったとしても、余計にそのような「書ける、書けない」「できる、できない」で判断してはいけません。きっと、アホ認定されることでしょう。アホなのですから仕方ありませんが。
Option Explicit Option Base 1 Private Sub Workbook_Open() Dim vars As Variant ' csv形式の文字列をカンマで区切る vars = Split("a,b,c", ",") Debug.Print vars(0) ' a Debug.Print vars(1) ' b Debug.Print vars(2) ' c End Sub
小規模のスクリプトであれば、まだ大丈夫かもしれませんが、稀だと思います。あっという間にカオスな世界が誕生します。
なぜ、わざわざ混乱を招くようなオプションを追加する必要があるのか理解に苦しみます。お互い様ですが、あなたとわたしの常識は違います。どちらにも言えることは理解できます。
しかし、プログラムを作る人の意見としては「デフォルトでOK!余計なことはするな!」だと思います。
違いますか?まあ、反論は聞きませんけど。
ごめんなさい反論させていただきます。
私はOption Base 1にすることが多いです。
速度の関係上Rangeを配列にして処理をすることが多いのですが、そのときにOption Base 0を書いていても、インデックスの開始が自動で1になってしまいます。
なので開始が0と1の配列が混在してしまいループカウンタなどの扱いが悪くなってしまうので、私は基本的にOption Baseを1にしています。
‘ *****例*****
Option Base 1
Sub test()
‘ レンジを取得
Dim getRange As Range
Set getRange = ActiveSheet.Range( “A1:B10” )
‘ 配列にする
Dim getArray As Variant
getArray = getRange ‘ Option Base 0でも要素の開始が自動で1からになる
Dim setArray() As Variant
‘ Option Base 0で要素数を同数にしたい場合はUBound(getArray)-1にしないといけない
Redim setArray(UBound(getArray), 1)
Dim i As Integer
‘ 何らかの加工をする
For i = 1 To UBound(getArray, 1)
‘ Option Base 0だとsetArrayのiをi-1にしないといけない
setArray(i, 1) = getArray(i, 1) + getArray(i, 2)
Next i
End Sub
サンプルスクリプトミスってたらごめんなさい。
好みの問題もありますが、私がSplit関数をあまり使わないのとCOBOLなど配列の開始が1からのプログラミング言語もあるので、Option Base1でいいかなと思っています。
もしRangeを配列にしたときに0から開始にできる方法があるなら教えてください。
ピンプクさんの場合はFor Each使えばいいだけな気が
for each でも確かにいけますけど、二次元配列をfor eachで処理させるとその中のIfの論理式が見辛くなって良くないと思われますので、
Dim getArray() as Variant
の直後に
ReDim getArray(1 To getRange.Rows.Count)
とするのがよいかと思われます
からくりを言えば、Option Baseのスコープがモジュールだからですね。
Option Baseはモジュールを超えて越境はしない。
従って、複数のモジュールで成り立っていれば、下限は想定不能になる。
結局、自分で責任を持てない外界からの変数はLBoundを怠るなになるかと思います。
自分で責任を持てるモジュール内の変数は自分ルールでいいと思いますが。