【Excel VBA】配列の動的確保(配列の要素数を増やす方法)

りゅう
こんにちは!りゅう(@ryupong_b)です。
今回は、配列の動的確保について解説していきます。
はじめに

今回は、配列の動的確保について解説していきます。
配列を取り扱うには必須知識だと個人的には思っています。
「動的確保とは?」から説明していきますので、最後までお付き合いください!

この記事を読むメリット
  • 動的確保の概念が分かります
  • 1次元配列から多次元配列まで、動的確保の方法が分かります
  • コピーするだけで使える、汎用的なソースコードを掲載しています

動的確保とは

配列の動的確保とは、「配列の要素数を動的に増加すること」を指します。
以下をイメージいただければ分かりやすいかと思います。

動的確保前

配列の要素数を追加したい

動的確保後

配列の要素数を追加

めい
配列を宣言するときに、どれだけの要素数を確保すれば良いのかわからない時があったんだよね。
りゅう
極端な話、配列に値を入れる直前に動的確保で要素数を拡張すればOKです。

使用例

配列の要素数を変更するには ReDimステートメントを使用します。
ReDimステートメントは、その名の通り変数の再宣言を行うステートメントです。
ReDimステートメントを使用する際は、拡張する対象の配列変数名と、配列要素数を指定するようにしましょう。

構文

ReDim [Preserve] 配列変数(n)

ReDimを実行すると、配列に格納されている値がすべてクリアされてしまいます。
ReDim後も値を保持したい場合は、Preserveキーワードを指定すると値が引き継がれます。

以下にサンプルコードを示します。

サンプルコード
Public Sub addArrayElement()

    Dim arr() As String ' 文字列型配列

    ' 配列の 0番目を確保し、文字列 "A"を代入
    ReDim arr(0)
    arr(0) = "A"

    ' 配列の 1番目を確保し、文字列 "B"を代入
    ReDim Preserve arr(1)
    arr(1) = "B"

End Sub
りゅう
配列変数「arr」を要素数指定なしとして宣言しています。
その後、0 ~ 1番目の要素を順々に確保するソースコードです。
このように、ReDimステートメントを使用すれば柔軟に要素数を増加できます。
めい
上記は説明用のサンプルとなっていますが、実際に使用する際はループ内で動的に要素を確保したいかと思います。
後ほど応用編としてサンプルコードを掲載しておりますので、ご参考としてください。

多次元配列の動的確保

先ほどご紹介したのは 1次元配列を取り扱ったものでしたが、多次元配列の場合の解説をします。
多次元配列であっても、ReDimステートメントを使用します。

サンプルコード
Public Sub addArrayElement()

    Dim arr() As String ' 文字列型配列

    ' 配列の 1次元目を2、2次元目を0番の要素を確保する。
    ReDim arr(2, 0)
    arr(0, 0) = "A"
    arr(1, 0) = "B"
    arr(2, 0) = "C"

    ' 2次元目を拡張する。
    ReDim Preserve arr(2, 1)
    arr(0, 1) = "X"
    arr(1, 1) = "Y"
    arr(2, 1) = "Z"

End Sub
りゅう
3次元配列でも同様、カンマ区切りでそれぞれの次元要素数を ReDimステートメントにて指定します。

実行結果

ReDimステートメントでは、配列の最終次元のみ拡張可能となっています。
上記例では、2次元目の拡張を行っていますが、1次元目の拡張を実施するとエラーとなりますのでご注意ください。

めい
不便だけど、こればっかりは仕様なので仕方ないね…。

サンプルコード(応用編)

実践で使えそうなサンプルコードを掲載いたします。

共通部品化

配列に値を追加するという目的の部品として、動的確保処理をラップすることをオススメします。
紹介するソースコードは、値を追加したい配列と、追加したい値を引数に指定すると要素を確保しつつ値を設定する処理となります。

前提

Sheet1に以下の文字列があり、これらの文字列を1次元配列に格納します。

サンプルコード
Public Sub main()

    Dim arr() As Variant        ' 配列
    Dim endRowIndex As Long     ' Sheet1 最終行番号
    Dim cellValue As Variant    ' セルの値

    ' Sheet1の最終行を取得する
    endRowIndex = ThisWorkbook.Worksheets(1).UsedRange.Rows.Count

    Dim i As Long
    For i = 1 To endRowIndex

        ' *** Sheet1 1列目を最終行分ループする ***

        ' セルの値を取得
        cellValue = ThisWorkbook.Worksheets(1).Cells(i, 1).Value

        Call addArrayElementForVariant(arr, cellValue)
    Next i

End Sub

Public Sub addArrayElementForVariant(ByRef arr() As Variant, ByVal element As Variant)

    If (Not arr) = -1 Then

        ' 配列が空の場合
        ReDim arr(0)
    Else

        ' 配列が空ではない場合
        ReDim Preserve arr(UBound(arr) - LBound(arr) + 1)
    End If

    ' 配列に値を格納
    arr(UBound(arr) - LBound(arr)) = element
End Sub

実行結果

りゅう
addArrayElementForVariantをコピーしてお使いください。
注意点としては、本ソースコードは1次元のVariant型配列に限定している処理であるため、必要に応じてデータ型や次元数を変更していただければと思います。

あわせて読みたい
【Excel VBA】配列が空かどうかを判定する方法 はじめに 配列の動的確保などをする際、配列が空かどうかを判定することがあります。 マイナーな知識となりますが、覚えておいた方がいいと思いますので、掲載いたしま...
あわせて読みたい
【Excel VBA】配列の要素数を取得する方法 はじめに 配列はループして回すことが多いと思います。 今回は、配列の要素数の取得方法をご紹介します! この記事を読むメリット 配列の要素数を取得する方法が分かり...
よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

大手外資系コンサルティングファーム勤務。ExcelVBA歴は8年。金融関係のプロジェクトにて約100万レコードを処理するマクロの開発実績あり。ExcelVBAの基礎・応用情報を発信中。

コメント

コメントする

CAPTCHA