STEP 3 VBA編

5.ワークシート関数の利用

ここで述べたように、Excelのワークシート関数には、引数として配列を扱えるものが結構あります。
一見「セル範囲」を指定しているように見えても、実はその範囲の値を配列として処理しているのです。
「セル範囲」というのはVBAのデータ型で言うとRangeですが、実際にRange型の引数しか指定できないのは、RANKやOFFSET、SUMIF、COUNTIF、PHONETICなどです。
一方、SUMや、VLOOKUPの「範囲」のような引数は、Range型ではなくVariant型であり、セル範囲として与えられたとしても、最終的には配列的に処理されます。さらに、セル範囲ではなく、直接配列を指定することも可能です(こちらも参照)。

これらの「配列を扱える」ワークシート関数の多くは、VBAのコードの中で、2次元までの配列を処理するために利用することができます。
たとえば、数値の配列の合計を求めたい場合、通常ならループで各数値を合計していくといった処理になります。
さらに、バリアント型で数値や文字列が混在している配列の数値だけの合計を求めたいといった場合は、ループの中で各要素を調べ、数値だった場合だけ加算するといった処理が必要となります。
このような処理にSUM関数を利用すれば、いずれにしても、引数としてその配列を放り込んでやるだけでいいわけです。
ワークシート関数を利用する一般的な方法は、やはりWorksheetFunctionを使ったものでしょう。

Dim r() As Variant
r() = Array(10, "a", 5, "あ", 2)
MsgBox WorksheetFunction.Sum(r)

また、ここで紹介しているEvaluateメソッドを利用して、配列を関数で処理することも可能です。

MsgBox [SUM({10,"a",5,"あ",2})]

一方、次の例は、配列として作成したテーブルから、得点に応じたランクを取り出すものです。

Dim r() As Variant
r() = [{0,10,30,50;"D","C","B","A"}]
MsgBox WorksheetFunction.Lookup(42, r())

もうひとつ、ワークシート関数を利用した便利な配列操作のテクニックを紹介しておきましょう。
ここで紹介している通り、バリアント型の変数や配列変数には、セル範囲の値を直接代入することができ、配列としてコードの中で利用できます。
しかし、この方法で取り出された配列は、たとえ1行だけであっても2次元配列となり、JoinやFilterといったVBAの関数で処理することはできません。
また、1行だけの2次元配列を1次元配列に変換する簡単な方法も、VBA自体には(たぶん)用意されていません。
しかし、ExcelのVBAでは、ワークシート関数のINDEXTRANSPOSEを利用することで、このような変換が行えます。
次のコードは、いずれも、セル範囲の文字列を1次元配列にして結合し、1つのセルに代入するものです。

Range("A1").Value = Join(WorksheetFunction.Index(Range("A3:E3").Value, 1, 0), "")
Range("A1").Value = Join([TRANSPOSE(TRANSPOSE(A3:E3))],"")








なお、上の例は1行のセル範囲を1次元配列にするものですが、1列のセル範囲であれば1回のTRANSPOSEで1次元配列にできます。

Range("A1").Value = Join([TRANSPOSE(A3:A7)],"")

また、INDEXを利用して、複数行×複数列の2次元配列から、指定した1行だけを1次元配列として取り出すことも可能です。同様に、1列だけを取り出して、TANSPOSEでやはり1次元配列にすることができます。

<4.配列を利用したセル操作    6.配列の受け渡し>