VBA ループ処理で配列に要素を追加していく
VBA
でループ処理で配列に要素を追加していく方法を紹介します。
配列が初期化されているかどうか判定するisArrayEx
ファンクションについては後述します。
詳しくはVBA 配列が初期化されているかどうかを判定するで紹介しています。
Dim arr() As String
For i = 0 To 4
If isArrayEx(arrPkey) = -1 Then
'初期化されていないので初期化
ReDim Preserve arrPkey(0)
Else
'初期化されているので要素を追加
ReDim Preserve arr(UBound(arr) + 1)
End If
arr(UBound(arr)) = i * 2
Next
'結果
'arr(0) 0
'arr(1) 2
'arr(2) 4
'arr(3) 6
'arr(4) 8
For
文のループ処理で配列の要素を1つづつ追加しながら、値を設定しています。
Ubound
関数は、指定した配列の最大のインデックスを返します。
Ubound
関数で取得した結果 + 1を配列の要素数として再定義していくことによって、配列の要素を増やしていきます。
配列が初期化されていない場合はUBound
関数が使えないため、VBA 配列が初期化されているかどうかを判定するで紹介した方法で、場合分けをしています。
また、配列を再定義するコマンドReDim 配列
ですが、これだと配列の各要素の値が全てクリアされてしまいます。
配列の各要素を保持したまま配列を再定義するにはReDim Preserve 配列
のように、Preserve
を追加します。
以下のようにループ処理で実装する前に、1ステップづつ実装していくとイメージがつかめるかと思います。
Dim arr() As String
ReDim Preserve arrPkey(0) '初期化
'Ubound(arr)の結果は0(0が最大のインデックス)
arr(UBound(arr)) = "a"
ReDim Preserve arr(UBound(arr) + 1) '値を保持したまま配列を最大のインデックス+1で再定義
'Ubound(arr)の結果は1(1が最大のインデックス)
arr(UBound(arr)) = "b"
ReDim Preserve arr(UBound(arr) + 1) '値を保持したまま配列を最大のインデックス+1で再定義
'Ubound(arr)の結果は2(2が最大のインデックス)
arr(UBound(arr)) = "c"
配列の初期化判定
配列の初期化判定にはsgn
関数を使用する方法がよく紹介されていますが、この方法だと環境によってエラーになることがあります。(詳しくはVBA 配列が初期化されているかどうかを判定するで紹介しています)
そのため、以下のURLで紹介しているファンクションを使用します。
参考URL: https://qiita.com/satoko138/items/7e06dda56683065968f7
参考ページより抜粋
'--------------------------------------------------------------
'機能:引数が配列か判定し、配列の場合は空かどうかも判定する
'戻り値:判定結果(1:配列 / 0:空の配列 / -1:配列ではない
'--------------------------------------------------------------
Public Function isArrayEx(varArray As Variant) As Long
On Error GoTo ERROR_
If IsArray(varArray) Then
isArrayEx = IIf(UBound(varArray) >= 0, 1, 0)
Else
isArrayEx = -1
End If
Exit Function
ERROR_:
If Err.Number = 9 Then
isArrayEx = 0
Else
'想定外エラー
End If
End Function