Excel VBA | 超初心者(Excel操作+マクロ体験):基本文法 - 動的配列

Excel VBA VBA
スポンサーリンク

動的配列って何が「動的」なのか?

前回の「配列宣言」は、こんな形でしたよね。

Dim scores(1 To 5) As Long
VB

これは「5個分」と最初に決めてしまう配列です。
こういうのを「固定配列(固定長配列)」と言います。

でも、実務ではよくこうなります。

  • 何件データが来るか、実行してみないと分からない
  • 条件に合ったデータだけ集めたいので、件数が読めない
  • 途中で「もっと箱が必要になった」「逆に減らしたい」

こういう「サイズが変わるかもしれない」状況で使うのが 動的配列 です。
一言で言うと、

「最初はサイズを決めず、あとから自由に増やしたり減らしたりできる配列」

です。


動的配列の基本:宣言と ReDim の流れ

まずは「サイズなし」で宣言する

固定配列との一番の違いは、宣言のときに「()の中を空にする」ことです。

Dim scores() As Long   ' サイズはまだ決めない
VB

この時点では、scores は「箱の数がまだ決まっていない配列」です。
ここが「動的」のスタート地点です。

実際に使うときに ReDim でサイズを決める

必要なサイズが分かったタイミングで、ReDim を使って箱の数を決めます。

ReDim scores(1 To 5)
VB

これで、scores(1)~scores(5) が使えるようになります。
イメージとしては、

「Dim で“動的配列としての箱”を用意」
「ReDim で“何個並べるか”を決める」

という二段構えです。

具体例:5人分の点数を動的配列で持つ

Sub SampleDynamicBasic()

    Dim scores() As Long   ' 動的配列として宣言
    Dim i As Long

    ReDim scores(1 To 5)   ' ここで5人分と決める

    For i = 1 To 5
        scores(i) = i * 10
    Next i

    MsgBox scores(3)   ' 3人目 → 30

End Sub
VB

この例だけ見ると「固定配列でもよくない?」と思うかもしれません。
その通りで、「最初から5人と分かっているなら固定配列で十分」です。

動的配列が本領発揮するのは、「何人か分からない」ときです。


実務っぽい例:A列のデータ件数に合わせて配列サイズを決める

データ件数が実行時まで分からないケース

例えば、A列にデータが何行あるか分からないけれど、
「A列の値を全部配列に読み込みたい」とします。

このとき、動的配列はこう使えます。

Sub SampleDynamicFromSheet()

    Dim scores() As Variant
    Dim lastRow As Long
    Dim i As Long

    ' A列の最終行を求める(よく使う書き方)
    lastRow = Cells(Rows.Count, "A").End(xlUp).Row

    ' データ件数に合わせて配列サイズを決める
    ReDim scores(1 To lastRow)

    ' A列の値を配列に読み込む
    For i = 1 To lastRow
        scores(i) = Range("A" & i).Value
    Next i

    MsgBox "配列に " & lastRow & " 件のデータを読み込みました。"

End Sub
VB

ここでのポイントは、

  • Dim scores() As Variant で「サイズ未定の配列」として宣言
  • 実際のデータ件数(lastRow)を調べてから
  • ReDim scores(1 To lastRow) でピッタリのサイズにする

という流れです。

「データが何件あるか分からないけど、無駄なく箱を用意したい」
というときに、動的配列はとても相性がいいです。


ReDim で「サイズを変える」ときの超重要ポイント

ReDim し直すと、中身は消える

動的配列は、ReDim を何度でも呼び出してサイズを変えられます。

ReDim scores(1 To 3)
scores(1) = 10
scores(2) = 20
scores(3) = 30

ReDim scores(1 To 5)   ' ここでサイズを変える
VB

ここで注意すべきなのは、
普通の ReDim は「前の中身を全部捨てて、新しく作り直す」 ということです。

上の例だと、10,20,30 は消えてしまい、
scores(1)~scores(5) は「中身が初期化された状態」になります。

「サイズを変えたいけど、中身は残したい」
というときに使うのが、次のキーワードです。


ReDim Preserve で「中身を残したままサイズ変更」

Preserve の役割

Preserve を付けると、

「今入っているデータを残したまま、配列のサイズを変更する」

ことができます。

ReDim Preserve scores(1 To 5)
VB

こう書くと、

  • もともとあった scores(1)~scores(3) の値はそのまま
  • scores(4), scores(5) が新しく追加される

という動きになります。

具体例:見つかったデータを順に追加していく

例えば、「A列の中で“完了”と書かれている行だけを配列に集めたい」とします。
何件あるか分からないので、見つかるたびに配列を1つずつ増やしていきます。

Sub SampleDynamicPreserve()

    Dim results() As Long   ' 行番号を入れる配列
    Dim r As Long
    Dim count As Long

    count = 0

    For r = 1 To 100
        If Range("A" & r).Value = "完了" Then

            count = count + 1

            If count = 1 Then
                ReDim results(1 To 1)
            Else
                ReDim Preserve results(1 To count)
            End If

            results(count) = r   ' 見つかった行番号を格納
        End If
    Next r

    If count > 0 Then
        MsgBox "完了は " & count & " 件見つかりました。最初の行は " & results(1) & " 行目です。"
    Else
        MsgBox "完了は見つかりませんでした。"
    End If

End Sub
VB

やっていることを言葉で整理すると、

  • 「完了」を見つけるたびに count を1増やす
  • 初回は ReDim results(1 To 1) で1個分の配列を作る
  • 2回目以降は ReDim Preserve results(1 To count) で、
    それまでの中身を残したまま、箱を1つ増やす
  • 新しく増えた位置(results(count))に行番号を入れる

という流れです。

ここでのキモは、
「ReDim だけだと中身が消える。中身を残したいなら ReDim Preserve」
という点です。


ReDim Preserve の制限(最後の次元しか変えられない)

少しだけ踏み込んだ話ですが、
ReDim Preserve には重要な制限があります。

「多次元配列のとき、変えられるのは“最後の次元”だけ」

というルールです。

例えば、

Dim table() As Long
ReDim table(1 To 3, 1 To 2)
VB

という二次元配列があったとします。
このとき、

ReDim Preserve table(1 To 5, 1 To 2)   ' これはエラー(1次元目は変えられない)
ReDim Preserve table(1 To 3, 1 To 4)   ' これはOK(2次元目=最後の次元だけ変更)
VB

という違いが出ます。

超初心者のうちは、
「ReDim Preserve は“最後の次元だけ”サイズ変更できる」
くらいの理解で十分です。


動的配列を使うときの考え方のコツ

いつ動的配列を選ぶべきか

「固定配列で足りるか?動的配列にすべきか?」の目安はシンプルです。

  • 必要な要素数が、コードを書く時点で“確定している”
    → 固定配列でOK
  • 必要な要素数が、“実行してみないと分からない”
    → 動的配列を検討する価値が高い

特に、Excelのシートからデータを読み込むときは、
「何行あるか分からない」が日常茶飯事なので、
動的配列の出番が多くなります。

「箱の数をあとから決める」という発想に慣れる

固定配列は、

「最初に“何個必要か”を決めてから箱を並べる」

動的配列は、

「とりあえず“箱の種類”だけ決めておいて、
 実際に必要になったタイミングで“何個並べるか”を決める」

という違いです。

この発想に慣れると、

  • 無駄に大きな配列を用意しなくて済む
  • データの増減に強いコードになる

というメリットが出てきます。


まとめ:動的配列は「サイズ未定の配列を、あとから自由に育てる仕組み」

動的配列の本質を一言で言うと、

「サイズをあとから決めたり、変えたりできる配列」

です。

押さえておきたいポイントをギュッとまとめると、

  • Dim a() As 型 で「サイズ未定の配列」として宣言する
  • 実際に使うときに ReDim a(1 To n) でサイズを決める
  • サイズを変え直すとき、普通の ReDim は中身が消える
  • 中身を残したいときは ReDim Preserve a(1 To n) を使う
  • 「何件あるか分からない」「条件に合うものだけ集めたい」ときに特に強い

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