複数の一次元配列を結合して一つの配列にまとめる関数

以下のVBAコードは、複数の一次元配列を結合して一つの配列にまとめる関数 merge1DArray と、配列が初期化されているかどうかを確認する関数 IsInitialized を含んでいます。また、サンプルコードとして、3つの文字列配列を結合する例も示されています。

詳しい解説

1. merge1DArray 関数

この関数は、複数の一次元配列を一つの配列に結合して返します。

'***********************************************
'* 一次配列を結合する関数
'* 引数arr():一次元配列の配列を受け取ります
'* 戻り値:結合された一次配列
'* 参考url:https://qiita.com/yakkeman/items/db6313e66cb3c9c4cc49
Function merge1DArray(arr() As Variant) As Variant
    Dim mergedArray() As Variant  ' 結合後の配列を格納する変数
    Dim i As Long, j As Long, index As Long: index = 0  ' カウンタとインデックス変数
    
    ' 外側の配列(arr)の各要素(一次元配列)を順に処理します
    For i = LBound(arr) To UBound(arr)
        
        ' 配列が初期化されているか確認
        If IsInitialized(arr(i)) Then
            ' 結合する配列(mergedArray)のサイズを調整
            ReDim Preserve mergedArray(index + UBound(arr(i)) - LBound(arr(i)))
            
            ' 各要素をmergedArrayにコピー
            For j = LBound(arr(i)) To UBound(arr(i))
                mergedArray(j + index) = arr(i)(j)
            Next j
            
            ' 次の配列の要素を追加するためのインデックスを更新
            index = index + UBound(arr(i)) - LBound(arr(i)) + 1
        End If
        
    Next i
    
    ' 結合された配列を戻り値として返す
    merge1DArray = mergedArray
End Function
各行の説明
  • mergedArray() As Variant: 結合結果を格納する配列です。初期状態ではサイズが未定義の動的配列です。
  • index As Long: 結合した配列に要素を追加する際のインデックスを管理します。
  • LBoundUBound: 配列の下限(最初のインデックス)と上限(最後のインデックス)を取得する関数。For ループ内で配列の要素を順に処理します。
  • ReDim Preserve: 配列のサイズを動的に変更します。Preserve キーワードを使うことで、既存の要素を保持したままサイズを拡張できます。
  • IsInitialized: 配列が初期化されているかどうかを確認します。

2. IsInitialized 関数

この関数は、配列が初期化されているかどうかを確認します。動的配列が初期化されていない場合、UBound 関数を呼び出すとエラーが発生するため、エラーハンドリングを使って初期化済みかどうかを判別します。

'***********************************************
'* 配列が初期化されているかをチェックする関数
'* ary:対象となる配列
'* 戻り値:配列が初期化済みならTrue、そうでなければFalseを返す
'* 参考url:https://qiita.com/nkojima/items/7f8299b3299226a97abb
Function IsInitialized(ary As Variant) As Boolean
    On Error GoTo NOT_INITIALIZED_ERROR  ' エラーが発生した場合、指定されたエラー処理に飛ばす
    Dim length As Long: length = UBound(ary)  ' 配列の上限値を取得。エラーが発生する場合は未初期化
    IsInitialized = True  ' 正常に上限値を取得できた場合はTrueを返す
    Exit Function

' 配列が初期化されていない場合のエラーハンドリング
NOT_INITIALIZED_ERROR:
    IsInitialized = False  ' 初期化されていない場合はFalseを返す
End Function
各行の説明
  • On Error GoTo: エラーハンドリングのための文。UBound でエラーが発生した場合、指定されたエラーハンドリングラベル NOT_INITIALIZED_ERROR にジャンプします。
  • UBound: 配列が初期化されていれば上限インデックスを取得し、初期化されていなければエラーが発生します。
  • NOT_INITIALIZED_ERROR: 配列が未初期化の場合、ここに飛ばされ、False を返します。

3. sample サブルーチン

このサブルーチンは、merge1DArray 関数の動作をテストするために書かれています。3つの一次元配列を作成し、それらを結合した結果をデバッグ出力します。

Private Sub sample()
    Dim arr1(3) As String, arr2(1) As String, arr3(2) As String  ' 3つの一次元配列を宣言
    Dim arr(2) As Variant  ' 上記配列を格納するVariant型の配列
    Dim mergedArray() As Variant  ' 結合された配列を格納する配列
    Dim i As Integer
    
    ' 各配列に値を設定
    arr1(0) = "あいうえお"
    arr1(1) = "かきくけこ"
    arr1(2) = "さしすせそ"
    arr1(3) = "たちつてと"
    
    arr2(0) = "なにぬねの"
    arr2(1) = "はひふへほ"
    
    arr3(0) = "まみむめも"
    arr3(1) = "やゆよ"
    arr3(2) = "らりるれろ"
    
    ' 配列をVariant型の配列に格納
    arr(0) = arr1
    arr(1) = arr2
    arr(2) = arr3
    
    ' merge1DArray関数で配列を結合
    mergedArray = merge1DArray(arr)
    
    ' 結合された配列の各要素をデバッグウィンドウに出力
    For i = LBound(mergedArray) To UBound(mergedArray)
        Debug.Print mergedArray(i)
    Next i
End Sub
サブルーチンの動作
  • 配列の設定: arr1, arr2, arr3 に文字列を設定します。
  • 配列の結合: merge1DArray 関数を使用して、これらの配列を一つの配列に結合します。
  • 結果の出力: 結合された配列の各要素を Debug.Print を使って出力します。

結論

このコードは、複数の一次元配列を結合するための汎用的な方法を提供しています。merge1DArray 関数は、配列を順に処理し、動的に配列のサイズを拡張しながら一つの配列に統合します。IsInitialized 関数は、配列が初期化されているかどうかを安全に確認するために重要です。

参考url

複数の一次元配列を連結して1つの一次元配列にする関数

参考にさせていただきました。空の配列がある場合にも対応するように改修しています。

【ExcelVBA】配列/動的配列の要素数を安全に求める

完全コピーにて、引用しています。

Follow me!