バリアント型を配列として使う


バリアント型変数は、どんなデータでも格納できる万能の型です。整数や文字列だけでなく、セル(Rangeオブジェクト)やワークシート(Worksheetオブジェクト)などのオブジェクトを格納することも可能です。もちろん、配列も格納できます。

Sub Sample39()
    Dim buf(3) As String, Member As Variant
    buf(1) = "tanaka"
    buf(2) = "suzuki"
    buf(3) = "yamada"
    Member = buf
    MsgBox Member(2)
End Sub

上のコードは、バリアント型変数Memberに、配列変数のbufを代入しています。代入のあと、変数Memberは配列として操作できます。

配列をバリアント型変数に入れる

バリアント型変数には、上記のように配列変数を代入することが可能ですが、一般的には「配列を返す関数」などの返り値を入れることが多いです。たとえば、Split関数は、区切り文字で区切られた要素を配列形式で返す関数です。CSVのようなデータを分割するときに便利です。

Split関数については、こちらをご覧ください

"tanaka,suzuki,yamada"というようなCSVデータを、Split関数で要素に分割するには、次のようにします。

Sub Sample40()
    Dim Member As Variant, i As Long
    Member = Split("tanaka,suzuki,yamada", ",")
    For i = 0 To UBound(Member)
        MsgBox Member(i)
    Next i
End Sub

Split関数は、"tanaka,suzuki,yamada"をカンマで区切って

(0)tanaka
(1)suzuki

(2)yamada

という3つの要素を持つ配列を返します。動的配列に格納することも可能ですが、たとえ事前に要素数がわかっていても、次のように要素数が固定されている配列に代入することはできません。

Sub Sample41()
    Dim Member(2) As String, i As Long
    Member = Split("tanaka,suzuki,yamada", ",")    ''エラー
    For i = 0 To UBound(Member)
        MsgBox Member(i)
    Next i
End Sub

他のプログラミング言語では、配列に配列を代入できるものもありますが、VBAではできません。そんなときは、一般的にバリアント型変数に代入します。

また、[ファイルを開く]ダイアログボックスを表示して、ユーザーからファイル名を受け取るApplicationオブジェクトのGetOpenFilenameメソッドも、引数MultiSelectにTrueを指定すると複数のファイルを選択できるようになります。このときの返り値も配列形式ですので、次のようにバリアント型変数で受けるのが一般的です。

Sub Sample42()
    Dim OpenFiles As Variant, i As Long
    OpenFiles = Application.GetOpenFilename(MultiSelect:=True)
    For i = 1 To UBound(OpenFiles)
        MsgBox OpenFiles(i)
    Next i
End Sub

蛇足ですが、上記2つのプロシージャのように、Split関数が返す配列と、GetOpenFilenameメソッドが返す配列ではインデックス番号が異なります。次のコードで試してみましょう。

Sub Sample43()
    Dim buf1 As Variant, buf2 As Variant
    ''Split関数の返り値をbuf1に入れる
    buf1 = Split("tanaka,suzuki,yamada", ",")
    MsgBox LBound(buf1) & " - " & UBound(buf1)
    ''GetOpenFilenameメソッドの返り値をbuf2に入れる
    buf2 = Application.GetOpenFilename(MultiSelect:=True)
    MsgBox LBound(buf2) & " - " & UBound(buf2)
End Sub

Split関数は、"tanaka,suzuki,yamada"を
(0)tanaka
(1)suzuki
(2)yamada

という配列で返しますが、GetOpenFilenameメソッドは「Book1.xlsx, Book2.xlsx, Book3.xlsx」という3つのファイルを選択した場合

(1)Book1.xlsx
(2)Book2.xlsx
(3)Book3.xlsx

という配列を返します。同じ3つの要素であっても、Split関数のインデクス番号は「0から2」で、GetOpenFilenameメソッドのインデックス番号は「1から3」となります。「何で違うんだ!」と文句を言っても始まりません。違うんですから、違うなりにプログラミングすればいいだけです。