「インデックスが有効範囲にありません。」
目次- はじめに
- 配列のインデックス
- 配列のインデックス範囲指定
- UBound(上限)とLBound(下限)
- Rangeを配列に格納する場合の注意
- コレクションでのインデックスエラー
- まとめ
- 関連記事:
はじめに
「インデックスが有効範囲にありません。」というエラーは、配列やコレクションのインデックス(添え字)で無効な値を指定した時に出力されます。 エラーが起こるコードを書いて検証してみます。
配列のインデックス
Array関数などで作った配列のインデックスは、何も指定しないと0から始まります。
Sub IntexTest1() Dim arr arr = Array("a", "b", "c") Debug.Print arr(3) 'エラー End Sub配列は以下のようにインデックスが設定されているので、上のプログラムはエラーとなります。
Split関数などで配列を生成する場合もインデックスは0から始まります。
配列のインデックス範囲指定VBAでは配列のインデックスの開始番号を指定して宣言する事ができます。 ただし、Array関数やSplit関数では使えなくなり以下のような書き方になるでしょう。
Sub IntexTest2() Dim arr(1 To 3) arr(1) = "a" arr(2) = "b" arr(3) = "c" Debug.Print arr(3) ' c End SubUBound(上限)とLBound(下限)
VBAの配列やコレクションはインデックス範囲を設定できるので、どのような場合でもインデックスの最初と最後を指定できるように、UBound(上限)とLBound(下限)という関数が用意されています。 これらを使えばある程度インデックスエラーを防ぐ事もできます。
尚、コレクションにはCountというプロパティ値が存在しますが、配列には要素数を取得する関数のようなものはないため、
UBound(配列) – LBound(配列) + 1
というふうに計算する必要があります。
Rangeを配列に格納する場合の注意
以下のようにバリアント型の変数にRangeを代入すると簡単に配列に値を代入する事が出来ます。 ただし、Rangeを配列に代入すると1行または1列の場合でも二次配列として格納されるので、以下のプログラムではエラーとなります。
Sub IntexTest3() Dim arr arr = Range("C4:E4") Debug.Print arr(UBound(arr)) 'エラー End Subローカルウインドウを見ると配列arrにどのように格納されているかわかります。
最後の値を表示させたい場合は、次のようにします。 Debug.Print arr( 1, UBound(arr))
コレクションでのインデックスエラー
よく使うコレクション(オブジェクトの配列)として、WorkbooksやWorksheetsコレクションがあります。 これらのコレクションでは、ブック名やシート名を指定して取得する事ができます。 その際、名前を間違ったりするとインデックスエラーが発生します。
Sub IndexTest4() Dim wb As Workbook Set wb = Workbooks("book1.xlsm") Debug.Print wb.Name End Sub上記のプログラムではbook1.xlsmが存在して既に開いている場合ならエラーは発生しません。 ブックを開いた状態にしなければ、Workbooksコレクションには入らないためインデックスエラーが発生します。
コレクションのインデックスを名前で指定する場合はスペルミスが無いか確認するようしましょう。
まとめ
インデックスエラーは、ちょっとした勘違いですぐ発生するのでプログラミングに慣れてくると原因が反射的に解るようになります。 慣れないうちは、ブレークポイントやStopコマンドでプログラムを停止させて、ローカルウインドウで配列の中身を確認すると良いでしょう。 コレクションなどでは、Debug.Print で Nameを表示させるなどしてスペルミスが無いかを確認するようにしましょう。
配列については以下のページも参考にしてみてください。 ・配列
関連記事: 漢字・英単語 暗記ツール Split関数が返す配列 ユーザーフォーム 第9回 リストボックス 「配列には割り当てられません」 文字と数値を切り分ける オートフィルターの使い方 配列要素をランダムに入れ替える ブックやシートの参照