VBAには配列のpopメソッドは無い
主にWeb系で扱うプログラミング言語には配列の操作を行うメソッドがあります。ここでは配列の終端にデータを追加する処理をVBA用にした関数を紹介します。
終端に追加する処理はプログラミング言語によって関数名は異なりますが、JavaScriptやPHPやRubyなど一般的には「pop」という名前が多いため、以下で紹介する関数はそれに合わせて「ArrayPop」という関数名にしています。
配列の先頭や終端にデータの追加や削除を行うには
VBAの配列は単にデータを複数保持しているだけですが、現在主流のプログラミング言語では配列はクラスとして管理されており、配列を操作するための関数が複数用意されていることが一般的です。
プログラミング言語によって関数名は異なりますが、配列を操作する関数として一般的には以下のようなものがあります。
関数名 | 用途 | 関数戻り値 |
---|---|---|
shift | 配列の先頭データを切り取る | 切り取った先頭データ |
unshift | 配列の先頭にデータを追加する | 追加後の配列要素数 |
pop | 配列の終端データを切り取る | 切り取った終端データ |
push | 配列の終端にデータを追加する | 追加後の配列要素数 |
これらの関数をVBAでも使えるように以下に説明します。なお、それぞれの実装方法が異なるためページを分けて説明しています。
- VBAの配列の先頭データを切り取る(shift)
- VBAの配列の先頭にデータを追加する(unshift)
- VBAの配列の終端データを切り取る(pop) 当ページ
- VBAの配列の終端にデータを切り取る(push)
配列の終端にデータを追加するコード(pop)
以下のコードは配列の終端のデータを切り取る関数です。JavaScriptやPHPなどでのpopメソッドになります。
VBAで配列の終端にデータを追加する場合、Redim Preserveで配列を拡張して実施します。popの場合も考え方は同じです。
使い方ですが、関数の引数には配列を渡し、関数の戻り値は切り取ったデータを返します。関数実行後は配列の要素数は終端データが無くなるため1減ります。
配列は1次元配列を対象としており、配列のデータ型はなんでもOKです。なんでもOKにするために、オブジェクト型かどうかの判定をIsObject関数で行い、オブジェクト型であれば値の代入方法でSetを使い、そうでなければ=で代入するようにしています。
IsObject関数の詳細については「VBAのオブジェクト変数かどうかを判定する(IsObject)」をご参照ください。
引数が配列でない場合は処理しません。また、配列の要素がない場合は終端データを戻り値用に切り取り、配列をクリアしています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 |
'// 終端を切り取る '// 引数:配列 '// 戻り値:切り取った先頭データ Function ArrayPop(ar As Variant) '// 引数が配列でない場合 If IsArray(ar) = False Then '// 処理せず抜ける Exit Function End If '// 配列要素数を取得 Dim iSize As Long '// 配列サイズ iSize = UBound(ar) '// 配列の終端を戻り値として取得 '// オブジェクト型変数の場合 If IsObject(ar(iSize)) = True Then Set ArrayPop = ar(iSize) '// プリミティブ型変数(IntegerやStringなど)の場合 Else ArrayPop = ar(iSize) End If '// 配列にデータが複数ない場合 If iSize = 0 Then '// 配列をクリア(終端データを削除)して処理を抜ける ReDim ar(0) Exit Function End If '// 終端の要素を削除 ReDim Preserve ar(UBound(ar) - 1) End Function |
使い方
上のArrayPop関数をString型の配列とRange型の配列のそれぞれの利用例です。
引数に配列を渡すだけですが、戻り値の受け取り方が配列のデータ型がオブジェクト型かそうでないかの2通りあります。
以下のコードのString型はプロパティやメソッドを持たないプリミティブ型の1つで、ArrayPop関数の結果を=の代入で取得できます。Range型はクラスのためオブジェクト型の1つになり、ArrayPop関数の結果をSetステートメントを使って取得します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 |
Sub ArrayPopTest() Dim ar() As String Dim s '// String型配列 ReDim ar(3) ar(0) = "abc" ar(1) = "bbb" ar(2) = "ccc" ar(3) = "ddd" '// 終端を切り取り s = ArrayPop(ar) Debug.Print s '// 切り取った ddd を出力 Debug.Print UBound(ar) '// 要素が1つの配列 ReDim ar(0) ar(0) = "!" '// 終端を切り取り s = ArrayPop(ar) Debug.Print s '// 切り取った ! を出力 Debug.Print UBound(ar) '// Range型配列 Dim r() As Range ReDim r(2) Dim ss As Range Set r(0) = Range("A1") Set r(1) = Range("B2") Set r(2) = Range("C3:D4") '// 終端を切り取り Set ss = ArrayPop(r) Debug.Print ss.Address(False, False) '// 切り取ったセルのアドレスC3:D4を出力 Debug.Print UBound(r) End Sub |
実行結果
ddd
2
!
0
C3:D4
1