更新日:、 作成日:

VBA 可変長な引数配列 ParamArray

はじめに

Excel VBA マクロで可変長な引数 (ParamArray) を持つ関数を作成する方法と、その引数の呼び出し方を紹介します。

ParamArray 引数名() As Variant のようにして、可変長な引数を持つ関数を作成できます。

Call 関数名(1, 2, 3) のようにして、渡した引数が配列になります。

合計を求めるときなど、渡す値の数が決まっていないときなどに使います。

関数に引数を渡すには「関数に引数を渡す」をご覧ください。
省略可能な引数 (Optional) の呼び出し方は「省略可能な引数と名前付き引数」をご覧ください。

可変長な引数を作成する

可変長な引数を作成するには ParamArray 引数名() As Variant のように入力します。必ず配列の Variant 型にします。ParamArray を付けると、任意の数の引数を配列に変換して受け取れます。

Sub 関数名(ParamArray 引数() As Variant)

End Sub

Function 関数名(ParamArray 引数() As Variant) As String

End Function

ParamArray を付けられるのは最後の引数だけです。

Sub 関数名(引数1 As Integer, ParamArray 引数2() As Variant)

End Sub

' これはできません。
Sub 関数名(ParamArray 引数1() As Variant, 引数2 As Integer)

End Sub

ParamArray の引数には ByVal, ByRef, Optional を指定できません。

ParamArray の引数があるときは、他の引数に Optional を指定できません。

' これはできません。
Sub 関数名(ParamArray ByVal 引数1() As Variant)

End Sub

' これはできません。
Sub 関数名(Optional ParamArray 引数1() As Variant)

End Sub

' これはできません。
Sub 関数名(Optional 引数1 As Integer = 1, ParamArray 引数2() As Variant)

End Sub

VBA では「Array 関数」や「Choose 関数」などで使われています。

可変長な引数に値を渡す

ParamArray の引数に , で区切って複数の値を渡します。その数の要素数を持った配列になります。

Sub 実行()
    Call サブ(1, 2, 3)         ' 1,2,3、     (0 To 2) の配列になる
    Call サブ("Tips", "found") ' Tips,found、(0 To 1) の配列になる
    Call サブ("Tips", 2)       ' Tips,2、    (0 To 1) の配列になる
End Sub

' この関数が呼び出されます
Sub サブ(ParamArray 引数() As Variant)
    Debug.Print(Join(引数, ",")) ' 配列をカンマ区切りで出力する
End Sub

ParamArray 以外の引数があるときは、それを先に指定してから ParamArray の引数に , で区切って値を渡します。

Sub 実行()
    Call サブ(1, 2, 3)         ' 2,3
    Call サブ("Tips", "found") ' found
End Sub

' この関数が呼び出されます
Sub サブ(引数1 As String, ParamArray 引数2() As Variant)
    Debug.Print(Join(引数2, ",")) ' 配列をカンマ区切りで出力する
End Sub

引数を省略する

ParamArray の引数は省略できます。そのときは要素数 0 To -1 という異常な配列が作成され、要素はありません。

Sub 実行()
    Call サブ ' (0 To -1) の配列になる
End Sub

' この関数が呼び出されます
Sub サブ(ParamArray 引数() As Variant)
    Debug.Print(LBound(引数))
    Debug.Print(UBound(引数))
End Sub

これは ParamArray の引数を For 文でループするときに、エラーにならないようにするためです。

Sub サブ(ParamArray 引数() As Variant)
    Dim i As Integer
    For i = 0 To UBound(引数)
        ' 引数が省略されたときはループしない
    Next
End Sub

引数に配列を渡す

ParamArray の引数に配列を渡したときは、引数の配列の要素に渡した配列が入っています。自動で展開されることはありません。

Sub 実行()
    Call サブ(Array("配列"))          ' Variant()
    Call サブ(Array("配列"), 2, "三") ' Variant(), Integer, String
End Sub

' この関数が呼び出されます
Sub サブ(ParamArray 引数() As Variant)
    Dim v As Variant
    For Each v In 引数
        Debug.Print(TypeName(v)) ' 引数の要素の型を出力する、配列のときは Variant()
    Next
End Sub

通常の引数に配列を渡すには、引数と同じ型の配列にする必要があります。

Sub 実行()
    Dim 動的() As Integer
    Dim 動的不一致 As Long
    Dim 静的(3) As Integer
    Dim 静的不一致(3) As Long
    Call サブ(動的)       ' 渡せる、 引数と同じ型
    Call サブ(動的不一致) ' 渡せない、引数と違う型
    Call サブ(静的)       ' 渡せる、 引数と同じ型
    Call サブ(静的不一致) ' 渡せない、引数と違う型
End Sub

Sub サブ(引数() As Integer) ' 引数の型 Integer の配列だけ受け取れる

End Sub
引数に配列を渡す条件については「配列」の「変数に配列を代入する」をご覧ください。