配列コピーの基本
VBAで配列をコピーする際、コピー先が動的配列であれば簡単な代入でコピーできますが、静的配列の場合はループ処理が必要です。この記事では、それぞれの方法を具体例とともに解説します。
配列の種類とコピー方法の違い
VBAの配列には2種類あります。
- 静的配列:配列の要素数を事前に指定する配列を「静的配列」と言います。(例:Dim ar(10))
- 動的配列:プログラムの処理中に要素数を変更できる配列を「動的配列」と言います。(例:Dim ar())
配列をコピーする際には、「コピー先の配列が静的配列か動的配列か」でコピーの仕方は以下のように異なります。
コピー先 | 方法 |
---|---|
静的配列 | 各要素をループでコピーする必要がある。代入不可。 |
動的配列 | 静的配列と同様にループでコピー可能だが、代入 |
なお、VBAの場合は値渡しでのコピーになります。参照渡しではありません。関数でByRefの参照渡しにしていても代入時には値渡しで設定されます。
注意点
先にも書きましたが、配列のコピーを代入で行う場合、コピー先の配列は次のように要素数を設定しない動的配列にしなければなりません。
1 |
Dim ar() |
私が実際にコードを書く場合は動的配列での代入を行うことがほとんどです。理由はラクだからです。
よほどの場合でない限り、コピー先を静的配列にしなければならないことはないと思いますので、通常は動的配列を利用して代入でのコピーで問題ありません。
動的配列の代入コピー(おすすめ)
動的配列であればシンプルな代入でコピーが可能です。これが最も効率的でコードも単純です。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
Sub DinamicArrayCopy() Dim ar1(3) As Variant '// コピー元の静的配列 Dim ar2() As Variant '// コピー先の動的配列 Dim i As Integer ar1(0) = 0 ar1(1) = 1 ar1(2) = "2" ar1(3) = "3" '// 配列の代入。この1行で配列のコピーが完了 ar2 = ar1 For i = 0 To UBound(ar2) Debug.Print ar2(i) Next End Sub |
実行結果
0
1
2
3
Variant型のar1という要素数が4の静的配列とar2という動的配列を用意し、ar1の各要素に数値または文字列が設定されたあとでar2に代入でコピーしてその内容をイミディエイトウインドウに出力しています。
Variant型のため暗黙の型変換を行っているためエラーは発生せず正常に処理されます。
Object型変数やユーザー定義型配列の代入コピー
Object型の変数をコピーする場合も代入で行います。
ここではセルを示すオブジェクト型であるRangeクラスオブジェクトを利用しています。コードには書いていませんがユーザー定義型の配列もオブジェクト変数と同様の書き方が可能です。
オブジェクト型のため各要素にセットする場合はSetステートメントが必要ですが、先のコードと同様に配列のコピーは代入で行います。
ミスしやすいのは代入の部分ではなく、オブジェクト型へのコピーのSetの付け忘れの方が多いかもしれませんね。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub ObjectArrayCopy() Dim ar1(3) As Range '// コピー元 Dim ar2() As Range '// コピー先 Dim i '// セル範囲を設定 Set ar1(0) = Range("A1") Set ar1(1) = Range("B2") Set ar1(2) = Range("C3") Set ar1(3) = Range("A4") '// 配列の代入 ar2 = ar1 For i = 0 To UBound(ar2) '// セル座標(Address)を出力 Debug.Print ar2(i).Address(False, False) Next End Sub |
実行結果
A1
B2
C3
A4
静的配列のコピー(ループでの各要素のコピー)
コピー先を要素数を指定している静的配列にする場合は代入でのコピーが出来ません。
そのためループによる設定を行うことになります。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
Sub StaticArrayCopy() Dim ar1(3) '// コピー元 Dim ar2(3) '// コピー先:静的配列 Dim i ar1(0) = 0 ar1(1) = 1 ar1(2) = "2" ar1(3) = "3" '// 配列のコピーを要素ごとに行う For i = 0 To UBound(ar1) ar2(i) = ar1(i) Next For i = 0 To UBound(ar2) Debug.Print "[" & ar2(i) & "]" Next End Sub |
実行結果
0
1
2
3
実践的な使い方とポイント
1. 動的配列を使うのが基本
特別な理由がない限り、コピー先は動的配列にすることをお勧めします。コードがシンプルになり、メンテナンス性も向上します。
2. 値コピーと参照について
VBAでは配列の代入は値コピーになります。コピー後に元配列を変更しても、コピー先には影響しません。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub ValueCopyDemo() Dim original(1) As String Dim copied() As String original(0) = "Original" original(1) = "Data" copied = original '// 値コピー original(0) = "Modified" '// 元配列を変更 Debug.Print "Original: " & original(0) '// → "Modified" Debug.Print "Copied: " & copied(0) '// → "Original"(変更されない) End Sub |
3. エラー回避のコツ
- コピー先が動的配列の場合:Dim arr() で宣言する。
- オブジェクト配列では要素設定時に Set の付け忘れに注意する。
- 配列のサイズが異なる場合のエラーハンドリングを考慮する。
まとめ
VBAでの配列コピーは、動的配列への代入が最も効率的で簡潔です。静的配列が必要な特殊なケース以外は、動的配列と代入を使用することで、保守性の高いコードが書けます。
方法 | 適用場面 | 長所 | 短所 |
---|---|---|---|
代入コピー(おすすめ) | 動的配列 | シンプル、高速 | 動的配列のみ |
ループコピー | 静的配列 | 柔軟性高い | コード量多い |