contents
|
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.ワークシート関数の利用で説明します。