配列を「開始番号を省略して」定義した場合に、
何番始まりにするかを設定する Option Base ステートメントを解説します。
なお、この方法は後述の通りあまり推奨できません。
使うためではなく既存コードを読むために、
本記事をお読みいただければと思います。
基本構文
' モジュール最上部にて Option Base 1 Sub 配列の開始番号テスト Dim 配列(5) Debug.Print Lbound(配列) ' ← 「1」が表示されます。 Dim 配列2(0 To 5) Debug.Print Lbound(配列2) ' ← 「0」が表示されます。 End Sub
解説
上記コードのようにモジュールの最上部に「Option Base 1」と記載すると、
開始番号を省略して定義した配列が「1」始まりの配列になるようになります。
※ Option Base 1 を書かない場合は「0」始まりの配列となります。
※ Option Base 1 設定下であっても「0 To」を明示すれば0始まりにできます。
このステートメントで使用できるのは「0」か「1」だけで、
Option Base 2 と記載すると、
コンパイル エラー: 修正候補: 0 または 1 |
という珍しいエラーを見ることができます。
Option Base 1 が無視される配列
Option Base 1 を使用したいと思うのは、
「必ず1始まりになるセル範囲から生成した配列と開始番号を合わせたい」
という目的が一番かと思います。
もし完璧にそうなるのであればよかったのですが、
残念ながらOption Base 1 が無視される配列が以下の通り存在します。
Split関数によって生成した配列
Split関数によって生成した配列は、
Option Base 1 下においても0始まりとなります。
Debug.Print LBound(Split("みかん,りんご,いちご", ",")) ' ← 「0」が表示されます。
よく使う関数で頻出のため、かなり厄介な仕様ですね。
DictionaryのKeys、Itemsによって取得した配列
Dictionaryに登録したKey、Itemを一次元配列で一括出力する、
Keysメソッド、Itemsメソッドもまた、Option Base 1 を無視します。
Dim Dicテスト As New Dictionary Dicテスト.Add 1, 1 Debug.Print LBound(Dicテスト.Items) Debug.Print LBound(Dicテスト.Keys)
こちらもDictionaryを使用する人にとっては頻出のコードですね。
ParamArrayによって渡された引数の配列
こちらはあまり頻出ではありませんが、ParamArrayもOption Base 1を無視します。
Sub テスト() Call ParamArrayの開始要素番号テスト(1, 2, 3, 4, 5) End Sub Sub ParamArrayの開始要素番号テスト(ParamArray 引数リスト()) Debug.Print LBound(引数リスト) ' ← 「0」が表示されます。 End Sub
Rangeオブジェクト.Valueから生成した配列
先ほど述べた通り、Range.Valueによって生成した配列は常に1始まりです。
これはOption Base 0 (=なにも書かない場合)を無視します。
各種コレクションのItem
Worksheets(○)に入れる数字(インデックス)や、
自作のCollectionのItemは常に1始まりです。
これはそもそも配列ではありませんので、もともとOption Baseの対象外です。
と、先ほど「Option Base 1 が無視される配列が存在します」といいましたが、
実際のところ「配列を取得する様々なメソッド・関数」で大抵無視されます(´∀`;)
結局「Dim 配列(○ To 10)」を省略した場合の開始番号くらいしか変更できません。
それならそれで覚えやすいと思いきや、
Debug.Print LBound(Array(1, 2, 3)) ' ← 「1」が表示されます。
と、なぜかArray関数だけはOption Base 1 の影響を受けます。
こんなのいちいち覚えていられませんし、バグの温床になりますよね。
そもそも「Dimにしか効かない」のであれば、
Dim 配列(1 To 10)
と、1始まりを明示してしまえばいいだけなんですから。
割と危険な設定ですので、Option Base 1は使用しないことをおすすめします。
使用されたコードを改修する際は上記の仕様を熟読し、
どの配列が0始まりで、どの配列が1始まりになっているか、
細心の注意を払ってマクロを改修してください。