Range、Variant、配列に対してWorksheetFunction.Transposeを使ってると微妙に挙動が違うことがあったので調査。
シートの範囲を渡した時の挙動差
関数の引数がRange型の場合とVariant型の場合でどういう変数が格納されたか確認してみた。
Range型の場合
Function rngtrns(rng As Range) arr1 = WorksheetFunction.Transpose(rng) arr2 = WorksheetFunction.Transpose(arr1) arr3 = WorksheetFunction.Transpose(arr2) arr4 = WorksheetFunction.Transpose(arr3) End Function
ローカルウィンドウを見ると、引数がRangeの場合、シートで指定した領域をRangeとして受け取り、transposeで出力されるのはvariant配列になっている。
Variant型の場合
引数の型を、As RangeからAs Variantに変えただけ。
Function varrngtrns(rng As Variant) arr1 = WorksheetFunction.Transpose(rng) arr2 = WorksheetFunction.Transpose(arr1) arr3 = WorksheetFunction.Transpose(arr2) arr4 = WorksheetFunction.Transpose(arr3) End Function
引数がVariantの場合、オブジェクト型として格納されその中にRangeがいる構成となっていました。
これがtransposeに入ると、後は同じVariant配列が戻ってきた。
後、transposeの動作として、行ベクトルを列ベクトルに変換したら、2次元配列が1次元配列になってしまうみたい。
arr2(1,2)って感じで、1次元配列に2次元配列の呼び出しするとエラーになるので、場合によってプログラムの書き換えが必要になりそう。。。
単純にRange型をVariant配列に代入した場合
列ベクトルでも2次元配列として、格納された。
Function rngtest3(rng As Range) Dim arrDrctCnv() As Variant arrDrctCnv = rng End Function
Dim arrDrctCnv() As Variant
に代入すると、Variant(1 to 1, 1 to 3)として、それぞれのRangeにいる値が代入された。
Dim arrDrctCnv As Variant
となってると、ObjectのRangeが代入されている。
また、transposeは渡されたものが行ベクトルだった場合は、兎に角1次元配列の列ベクトルに直す仕様みたい。。。
Range型は配列ではないし、値は持っていない。
Range型はシートの座標を参照渡ししてるだけであり、値はシートを参照している。
例えば、下記の様な関数を作成し、図のように実行すると9が出力される。
Function rngtest(rng As Range, i As Long, j As Long) rngtest = rng(i, j) End Function
A2:B2という1行2列の範囲を送っているのに、それをはみ出した範囲を指定してもエラーは出ず、その場所に該当するシートの値を読んでいる。
rngtestの「rng As Range」を「rng As Variant」に変更しても同じ挙動だったので、この場合VariantはRangeとして動いてるっぽい。
コメント