配列とは何か


配列に関しての動画を作りました。特に「配列はどんなときに使うのか」という4パターンをご紹介していますので、ぜひご覧ください。なお動画では、本稿で解説しているような「0号室を空き部屋とする」考え方には触れていません。Youtubeでは、ほかにもたくさんの動画を公開しています。チャンネル登録しておくと、あなたもExcelマスターになれるかも(笑)
Office TANAKAチャンネル

※再生すると音が出ます。会社や電車の中などではご注意ください。

配列のイメージ

一般的な変数には、ひとつの値しか格納できません。たとえば、次のコードは文字列型の変数bufを宣言しています。まず、変数に"田中"を格納していますが、次に"鈴木"を格納すると、先に入っていた"田中"は消えてしまいます。

Sub Sample29()
    Dim buf As String
    buf = "田中"
    MsgBox buf          ''田中が表示される
    buf = "鈴木"
    MsgBox buf          ''鈴木が表示される
End Sub

これは、長整数型など他の変数でも同じです。1つの変数には1つの値しか格納できません。そうではなく、1つの変数に複数の値を格納できるのが配列です。たとえば、一般的な変数は一戸建て住宅と考えられます。ある家屋に"田中家"が住んでいるとき、新しく"鈴木家"が引っ越してくると、その家は"鈴木宅"になります。

対して配列は、アパートやマンションなど集合住宅のようです。建物の中が複数の部屋に分割されていて、ひとつの建物に複数の家族が同時に居住できます。

たとえば「エクセル荘」というアパートがあって、部屋が3つあったとします。1号室には"田中さん"、2号室には"鈴木さん"、そして3号室には"山田さん"が、それぞれ住んでいたとします。これは、次のように表すことができます。

エクセル荘 の 1号室 には "田中さん"
エクセル荘 の 2号室 には "鈴木さん"
エクセル荘 の 3号室 には "山田さん"

簡略化して表すと

エクセル荘(1) は "田中"
エクセル荘(2) は "鈴木"
エクセル荘(3) は "山田"

です。

この状況をVBAで表すと、次のようなコードになります。

Sub Sample30()
    Dim エクセル荘(3) As String
    エクセル荘(1) = "田中"
    エクセル荘(2) = "鈴木"
    エクセル荘(3) = "山田"
    MsgBox "2号室の住人は、" & エクセル荘(2) & "です"
End Sub

配列を使用するときは、まず配列を宣言します。これは、一般的な変数と同じです。

上記の「Dim エクセル荘(3) As String」は、文字列型の変数「エクセル荘」という配列を宣言しています。同時に「エクセル荘(3)」のように、この配列には部屋が「3号室まで存在する」と定義しています。

配列に値を代入するのは、一般的な変数とおなじように「=」演算子を使います。このとき、左辺では、配列の何号室に格納するかを指定しなければなりません。「エクセル荘(2) = "鈴木"」は、配列"エクセル荘"の2号室に、"鈴木"という文字列を格納していることになります。

配列の先頭は0号室から始まる

前述のように「Dim buf(3) As String」は、配列bufに「3号室まで」部屋を用意するという定義です。では、この配列bufは何号室から始まっているのでしょう。実は、初期状態のVBAでは、配列は0から始まるというルールがあります。つまり「Dim buf(3) As String」は、

buf(0)
buf(1)
buf(2)
buf(3)

4部屋が存在していることになります。先のコード

Sub Sample31()
    Dim エクセル荘(3) As String
    エクセル荘(1) = "田中"
    エクセル荘(2) = "鈴木"
    エクセル荘(3) = "山田"
    MsgBox "2号室の住人は、" & エクセル荘(2) & "です"
End Sub

では、エクセル荘の0号室に該当する「エクセル荘(0)」という部屋が存在するものの、誰も入居していない状態です。

この「配列は要素(部屋)が0から始まる」というVBAの仕様は、ときどき"うっかりミス"を招きます。Excelのセル番地や、コレクションの要素番号などは、先頭が1から始まっているからです。たとえば、配列の要素0から格納されているデータをセルに代入するには、次のようにカウンタ変数を調整してやらなければなりません。

For i = 1 To 3
    Cells(i, 1) = buf(i - 1)
Next i

あるいは

For i = 0 To 2
    Cells(i + 1, 1) = buf(i)
Next i

のように。

「Option Base 1」というステートメントを使うと、配列の先頭を1から始めることもできますが、これはVBAの設定を変更すれば済むことではなく、毎回モジュールの先頭で明示的に入力しなければなりません。うっかり記述し忘れた日には、それこそ目も当てられません。

VBAでは配列の要素が0から始まるという点は忘れないでください。そして、運用で工夫をするのなら、要素0は使わないという考え方もできます。

Sub Sample32()
    Dim buf(3) As String, i As Long
    buf(1) = "tanaka"
    buf(2) = "suzuki"
    buf(3) = "yamada"
    For i = 1 To 3
        Cells(i, 1) = buf(i)
    Next i
End Sub

上のコードは、配列に格納した3つのデータを、セル範囲A1:A3に代入します。「Dim buf(3) As String」は

buf(0)
buf(1)
buf(2)
buf(3)

の4要素を使用可能にしていますが、buf(0)は使っていません。別に、配列の要素を1つ使わなかったからといって、大きな問題ではないでしょう。

標準的なVBAでは、配列の最小要素は0になります。しかし、必ずしもすべての配列が0から始まるわけではありません。配列を返すVBAの命令には、最小の要素が1から始まる配列を返すものもあります。そんなときは、配列の最小インデックス番号や最大インデックス番号を調べるための関数を使います。詳しくは、下記のページをご覧ください。

バリアント型変数を配列として使う