Variant型を使う時・使わない時

初級VBA

はじめに

 Variant型は、色々な変数型の代用ができ便利ですが、一方でVariant型にしたためにエラーが発生する場合もあります。
 Variant型を適切に使うには「使うべきでない時」と「使うべき時」を把握しておく必要があります。
 基本的なスタンスとしては、Variant型をなるべく使わないようにして、使うべきケースで利用するのが良いと思います。それぞれのケースを見ていきます。

Variant型を使わない方が良いケース


 以下は、よく初心者が陥る変数宣言のエラーです。

Sub sample(d As Double)
    Debug.Print d    
End Sub

Sub testCode()
    Dim a, b As Double
    a = 1
    b = 2
    sample a
    sample b
End Sub

 testCode関数を実行すると、内部でsample関数を呼びだしていますが、以下のようなエラーが出ます。

  コンパイルエラー:ByRef 引数の型が一致しません。

 このコードのエラーの原因は、2つあります。 一つ目は、
 Dim a, b As Double ×
 これでは、変数 a の型名を省略されたためにVariant型になってしまいます。
 本来なら以下のように宣言します。
 Dim a As Double, b As Double 
 
 そして二つ目がエラーを引き起こした原因です。
sample関数の引数が Double型なのにVariant型を渡しています。

 上記のような「引数の型が一致しません。」というエラーは、同じ数値型でも Double型なのに Long型を渡してしまったようなケースでも発生します。
 以下の例では3つともエラーとなります。

Sub testCode2()
    Dim s As String
    s = "1.12"
    sample s
    
    Dim l As Long
    l = 10
    sample l
    
    Dim v As Variant
    v = 10.1
    sample v
End Sub

 エラーを解消するためには、Double型に変換してから引数を渡せばOKです。
 Double型に変換するためには、Val関数や、CDbl関数を使います。
 Val関数では、変換した数値に応じた型に変換してくれるので便利です。

Sub testCode2()
    Dim s As String
    s = "1.12"
    sample Val(s)
    
    Dim l As Long
    l = 10
    sample CDbl(l)
    
    Dim v As Variant
    v = 10.1
    sample Val(v)
End Sub

 変数型を限定すれば、エラーが出る事でミスを見つけやすくなります。必要のない時には用途に応じた変数型を指定するようにして、Variant型は極力使わないようにした方が良いでしょう。

Variant型を使った方が良いケース

 場合によってはVariant型の方が良いケースがあります。主な例を2つ挙げます。

For Each In を使用する場合

For Each In はリストや配列から1つづつ要素を取り出す処理です。
要素を取り出すための変数は、Variant型か、オブジェクト型を使用する仕様となっています。

Sub UseVariant1()
'範囲内の文字数をカウントする
    Dim v As Variant
    Dim cnt As Long
    cnt = 0
    For Each v In Range("A1:A10")
        cnt = cnt + Len(v.Text)
    Next v
    Debug.Print cnt
End Sub

Split関数を使用する場合

 Split関数は、文字列を区切り文字で分けて配列を返しますが、配列の要素数は予めわからなかったり、失敗するケースもあります。
このような時でもVariant型なら柔軟に受け入れてくれます。

Sub UseVariant2()
'セル内の値を区切り文字列で配列に格納する
    Dim i As Long
    Dim arr As Variant
    
    arr = Split(Range("B2"), ",")
    
    For i = LBound(arr) To UBound(arr)
        Debug.Print "arr(" & i & ") = " & arr(i)
    Next i
End Sub

 2つのケースを紹介しましたが、Variant型を使用するケースは定番的な使い方をします。主にオブジェクトを扱ったり、動的な配列などを扱う時に利用します。

まとめ

 Variant型を使用しない方が良いケースと、使用した方が良いケースを見てきました。
 区別するには以下の点に注目しましょう。

 ・変数の宣言で型名を省略した場合は、Variant型になる。
 ・基本的には変数型を用途に合わせて宣言する。
 ・For Each In や Split などVariant型を使用すべき時に利用するようにする。

コメント

タイトルとURLをコピーしました