「インデックスが有効範囲にありません。」

エラー

はじめに

 「インデックスが有効範囲にありません。」というエラーは、配列やコレクションのインデックス(添え字)で無効な値を指定した時に出力されます。
 エラーが起こるコードを書いて検証してみます。

配列のインデックス

 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 Sub

UBound(上限)と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))

コレクションでのインデックスエラー

 よく使うコレクション(オブジェクトの配列)として、WorkbooksWorksheetsコレクションがあります。
 これらのコレクションでは、ブック名やシート名を指定して取得する事ができます。
 その際、名前を間違ったりするとインデックスエラーが発生します。

Sub IndexTest4()
    Dim wb As Workbook
    Set wb = Workbooks("book1.xlsm")
    
    Debug.Print wb.Name
End Sub

 上記のプログラムではbook1.xlsm存在して既に開いている場合ならエラーは発生しません。
 ブックを開いた状態にしなければ、Workbooksコレクションには入らないためインデックスエラーが発生します。

 コレクションのインデックスを名前で指定する場合はスペルミスが無いか確認するようしましょう。

まとめ

 インデックスエラーは、ちょっとした勘違いですぐ発生するのでプログラミングに慣れてくると原因が反射的に解るようになります。
 慣れないうちは、ブレークポイントStopコマンドでプログラムを停止させて、ローカルウインドウで配列の中身を確認すると良いでしょう。
 
 コレクションなどでは、Debug.Print で Nameを表示させるなどしてスペルミスが無いかを確認するようにしましょう。

 配列については以下のページも参考にしてみてください。
  ・配列

タイトルとURLをコピーしました