セル範囲を配列に、配列の要素をセル範囲に出力する処理は、配列を使う上で必ず行いますよね。この記事では、A列、B列に入っているデータを、セル範囲ー配列間でやり取りする方法を解説します。
ループ処理だとコーディングの効率が悪い
一番最初に思いつくのは、以下のように、セルをループ処理して配列に要素を格納する方法です。
1.セル範囲に合わせた配列を用意する
2.セル範囲と、用意した配列をFor Nextでアクセスし、配列にセルのデータを格納していく。
ループ処理のイメージ
コード
Sub ループ処理で配列に格納()
Dim Myrange(1 To 8, 1 To 2) As String
Dim i As Long, r As Long
For i = 1 To 8
For r = 1 To 2
Myrange(i, r) = Cells(i, r)
Next
Next
End Sub
二重のループ処理にならざるを得ず、コードの可読性が下がりますし、処理の回数も必要に応じて変更しなければならず、コードの使い回しがしにくいです。そこで、今回は別のアプローチをご紹介します。
「バリアント型変数 = セル範囲」で二次元配列になる。
ループ処理を使わず、セル範囲を配列に格納する方法は、以下のコードで可能になります。
コード
sub 範囲を配列に格納()
Dim Myrange As Variant
Myrange = Range("A1:B8")
End Sub
処理のイメージ
たったの2行で配列に格納できました。「え?これで格納出来てるの?」という声が聞こえて来そうなくらい簡単ですね。
Debug.printを使って、配列の要素にアクセスしてみます。
要素「A1」を取り出せました。配列にセル範囲が格納されていることが確認できました。
御覧のとおりループ処理は不要で、定義した変数にセル範囲を代入するだけです。変数が二次元配列へと自動的に変換されるので、①セル範囲に対応した二次元配列を用意して、②ループ処理にかけるという行程を省くことが出来ました。
配列に格納する範囲を指定する方法は色々
セル範囲を指定する方法には、Range(セル範囲)とする方法以外に、以下の三つの方法が存在します。
- バリアント型変数=Range(Cells(左上のセル番地),Cells(右下のセル番地))
- バリアント型変数= 起点セル.CurrentRegion
- バリアント型変数=シートオブジェクト.UsedRange
バリアント型変数=Range(Cells(左上のセル番地),Cells(右下のセル番地))で柔軟に範囲を指定する方法
コード
Myrange = Range(Cells(1,1),Cells(8,2)) 'Range("A1:B8")と同じ意味
Rangeの引数にCellsを使いました。第一引数に、セル範囲の左上、第二引数にセル範囲の右下のセル番地を記述することで、セル範囲を確定させています。
イメージ
Cellsを使うことから、変数をセル番地に入れることが出来るため、柔軟にセル番地を指定することが出来ます。
バリアント型変数= 起点セル.CurrentRegionでコーディングを楽にする方法
コード
Myrange = Range("A1").CurrentRegion
一番コーディングが楽です=実行時エラーが少ない方法です。
バリアント型変数=シートオブジェクト.UsedRangeで漏れなく範囲指定する方法
コード
Myrange = ActiveSheet.UsedRange
コーディングが楽で、なおかつセルのデータを漏れなく配列に格納することが出来ます。
データが存在するセルが飛び石になっている場合は、空白まで配列に格納することになることに注意です。
二つの注意点
バリアント型配列=セル範囲で配列に格納する方法には、覚えておくべき特徴が2点あります。
1.配列のインデックス番号は1から始まる
2.変数の型はVariant型にする必要がある。
注意点1.配列のインデックス番号は1から始まる
Debug.printで確認したとおり、セル範囲の左上の要素を取り出すのに、(1,1)としました。OptionBaseを1とせずとも、インデックス番号が1から開始されています。
注意点2.変数の型はVariant型にする必要がある。
セル範囲を格納する変数の型はVariant型にしました。
ここで、変数の型をString型に変更し、実行してみると、コンパイルエラーが発生し、「配列がありません」と表示されます。
なお、Range型にしても同じくコンパイルエラーになります。
配列からセル範囲への出力は、格納と逆の操作をするだけ
配列からセル範囲に出力する方法については、「バリアント型配列=セル範囲」という考え方で出来ました。セル範囲への出力は単純に格納の逆で、「セル範囲=バリアント型配列」とすれば良いので、ループ処理は不要になります。
ただ、出力する場合には、いちいちセル範囲を指定しなくても済むよう、便利な方法があります。
出力先のセル範囲のサイズを間違えるとエラーになる
セル範囲に配列からデータを転記するには、「セル範囲=バリアント型配列」にすれば良いところ、セル範囲の設定を間違えた場合、実行時エラーが発生します。
具体的には、出力先のセル範囲のサイズ<バリアント型配列のサイズとしてしまった場合です。
例えばこのデータに対して
次のようなコードを書いてしまった場合
Sub セル範囲のサイズを間違えた場合()
Dim MyArray As Variant
MyArray = Range("A1:B8")
Range("C1:D10") = MyArray'転記先のセル範囲を、配列より大きくしてしまった
End Sub
実行結果
配列のサイズを超えた部分がエラーになりました。
エラーを防ぐために(間違えたコードを書かないために)便利なのが、Resizeです。
Resizeの挙動
Resizeを使えば、起点セルから指定した行数、列数のセル範囲を指定することが出来ます。
Resizeの使い方
- 起点セルは、Resizeの引数の起点になるセルです。このセルを基準に、範囲を拡張します。
- 起点セルを左上にした、行数第1引数、列数第2引数のセル範囲を返します。
引数にUboundを使うと範囲指定が楽になる
Resizeは引数に行数、列数を指定しますので、二次元配列の行数、列数を与えれば、出力先のセル範囲=配列のサイズが指定出来ます。
AB列にデータ
コード
Sub ResizeにUboundを使う()
Dim MyArray As Variant
MyArray = Range("A1:B8")
Range("C1").Resize(UBound(MyArray, 1), UBound(MyArray, 2)) = MyArray
End Sub
実行結果
Uboundの詳しい挙動については、こちらを参考にしてください
コメント