[VBA]Range、Variant、配列の挙動調査

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として動いてるっぽい。

コメントを残す

メールアドレスが公開されることはありません。