STEP 3 VBA編

4.配列を利用したセル操作

Excelのワークシートは2次元配列と同じ構造です。
VBAの2次元配列(データ型や、固定長配列/動的配列は問いません)は、そのまま同じサイズのセル範囲に代入することができます。
配列よりも大きいサイズのセル範囲に代入した場合、対応する要素のないセルは#N/Aになります。

Dim a(1,1) As String
a(0, 0) = "A"
a(0, 1) = "B"
a(1, 0) = "C"
a(1, 1) = "D"
Range("B2:C4").Value = a()

また、セル範囲に入力されたデータは、Valueプロパティで取り出して、そのままバリアント型の動的配列、またはバリアント型の変数に代入することができます。

Dim a() As Variant
a() = Range("B2:C3").Value

なお、このとき、配列のインデックス番号の最小値は、Option Baseの設定に関係なく、1になります。
セル範囲に入力された数値を1つずつ操作していくような処理では、ループで1つ1つのセルから値を読み取り、処理した値を書き込んでいくよりも、いったん配列に取り出して、この配列に対してループで処理を行い、処理後の配列を再びセル範囲に代入し戻すようにしたほうが、ほとんどの場合、処理速度は向上します。

また、対象のRangeオブジェクトが複数の領域を持っている場合は、その1番目の領域の値だけが配列として取り出されます。たとえば、「Range("A2:B4,C4:E6,G1:G4").Value」であれば、A2:B4のセル範囲の値が3行×2列の配列として取り出されます。

ValueプロパティではなくFormulaプロパティを使用すると、各セルの値ではなく数式(を表す文字列)の配列を取り出すことができます。
ただ、この2次元配列の内容はあくまで文字列なので、さらにもう一度どこかのセル範囲に代入した場合、たとえ相対参照であっても、セル参照は変化しません。

Dim a() As Variant
a() = Range("B2:C3").Formula
Range("D5:E6").Formula = a()

この例の場合、わざわざ一度配列変数に収めなくても、セル範囲を直接セル範囲のFormulaに代入しても同じ結果になります。
また、Formulaを使用する必要があるのは右辺だけで、左辺についてはValueなどでも問題ありません。

Range("D5:E6").Value = Range("B2:C3").Formula

セル参照を位置に応じて変化させたい場合は、FormulaではなくFormulaR1C1プロパティを使うといいでしょう。

Dim a() As Variant
a() = Range("B2:C3").FormulaR1C1
Range("D5:E6").FormulaR1C1 = a()

この例もFormulaの場合と同様、セル範囲を直接セル範囲に代入することができます。

Range("E8:F9").Value = Range("B2:C3").FormulaR1C1

一方、VBAの1次元配列は、そのまま1行のセル範囲に代入することが可能です。

Range("B2:D2").Value = Array("A", "B", "C")

複数行のセル範囲に1次元配列を代入すると、各列に同じ要素が入った行が複数できます。

Range("B2:D5").Value = Array("A", "B", "C")

反対にセル範囲のデータを動的配列や変数に代入する場合、たとえ1行だけであっても、行数が1行の2次元配列になります。

Dim a() As Variant
a() = Range("B2:D2").Value

この場合も、配列のインデックス番号の最小値は、Option Baseの設定に関係なく、1になります。

つまり、この方法で取得した配列に対して、1次元配列を扱うJoinやFilterなどの関数は使用できません。
このような処理を実行したい場合は、1行だけの2次元配列を1次元配列に変換するという操作が必要です。
この方法については、5.ワークシート関数の利用で説明します。

<3.配列を操作する関数    5.ワークシート関数の利用>