VBA 省略可能な引数 Optional と名前付き引数

はじめに

Excel VBA マクロで省略可能な引数 (Optional) を持つ関数を作成する方法と、引数を省略して呼び出す方法を紹介します。

Optional 引数名 As 型名 = 既定値 のようにして、省略可能な引数を持つ関数を作成できます。引数を省略して呼び出されたときの既定値を設定できます。

Call 関数名(引数1:="1") のようにして、引数名を指定して値を渡せます。

関数に引数を渡すには「関数に引数を渡す」をご覧ください。
可変長な引数配列 (ParamArray) の呼び出し方は「可変長な引数配列」をご覧ください。
  • 目次
    • 省略可能な引数を作成する
    • 引数を省略して呼び出し
    • 名前を指定して呼び出し

省略可能な引数を作成する

省略可能な引数を作成するには Optional 引数名 As 型名 = 既定値 のように入力します。Optional を付けると省略可能になります。省略されたときの既定値を設定できます。

Sub 関数名(Optional 引数 As String = "既定値")

End Sub

Function 関数名(Optional 引数 As String = "既定値") As String

End Function

既定値を指定しないとその型の初期値になります。ただし省略したときの値を明示するためにも、必ず既定値を設定します。

Sub 関数名(Optional 引数 As String)

End Sub

Optional を付けられるのは最後の引数です。Optional の前の引数にも付けられます。

Sub 関数名(引数1 As Integer, Optional 引数2 As Integer = 2)

End Sub

Sub 関数名(引数1 As Integer, Optional 引数2 As Integer = 2, Optional 引数3 As Integer = 3)

End Sub

Optional が付いていない引数の前には付けられません。

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

End Sub

ByVal や ByRef と組み合わせられます。ParamArray とは組み合わせられません。

Sub 関数名(Optional ByVal 引数1 As Integer = 1, Optional ByRef 引数2 As Integer = 2)

End Sub

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

End Sub

VBA では「MsgBox 関数」や「StrComp 関数」などで使われています。毎回同じ引数を渡すときは、省略して既定値でその値を設定できると便利です。

引数を省略して呼び出し

引数を省略して関数を呼び出すには、何も入力しないだけです。省略したときは既定値が設定されます。省略しないときは、渡した値が引数の値になります。

Sub 実行()
    Dim 変数 As Integer
    変数 = 2

    Call サブ        ' 1、省略したときは既定値になる
    Call サブ(変数)  ' 2、値を渡すとその値になる
End Sub

' この関数が呼び出されます
Sub サブ(Optional 引数 As Integer = 1)
    Debug.Print(引数)
End Sub

複数の引数を省略するには、何も指定しないで , で区切ります。

Sub 実行()
    Call サブ("前")         ' 前23
    Call サブ(, "中")       ' 1中3
    Call サブ(, , "後")     ' 12後
    Call サブ("前", , "後") ' 前2後
End Sub

' この関数が呼び出されます
Sub サブ(Optional 引数1 As String = "1", Optional 引数2 As String = "2", Optional 引数3 As String = "3")
    Debug.Print(引数1 & 引数2 & 引数3)
End Sub

名前を指定して呼び出し

名前を指定して引数を渡すのに Optional を付ける必要はありません。ただ Optional が付いた引数でよく使われるのでここで紹介します。

引数に渡す値を 引数名:=値 のように入力すると、その引数に値を渡せます。名前を指定したときは、引数の順番は関係なくなります。

Sub 実行()
    Call サブ(引数1:="前")              ' 前23
    Call サブ(引数3:="後", 引数2:="中") ' 1中後
    Call サブ("前", 引数3:="後")        ' 前2後
End Sub

' この関数が呼び出されます
Sub サブ(Optional 引数1 As String = "1", Optional 引数2 As String = "2", Optional 引数3 As String = "3")
    Debug.Print(引数1 & 引数2 & 引数3)
End Sub

ただし、引数の順番が関係なくなるので、その後ろのすべての引数に名前を付ける必要があります。

Sub 実行()
    Call サブ(引数1:=1, 2)        ' エラー、引数2 も名前で指定する必要あり
    Call サブ(引数2:=2, 1)        ' エラー、引数1 も名前で指定する必要あり
    Call サブ(引数1:=1, 引数2:=2) ' OK
    Call サブ(引数2:=2, 引数1:=1) ' OK
End Sub

' この関数が呼び出されます
Sub サブ(引数1 As String,  引数2 As String)

End Sub

名前を指定した引数より後ろに定義されている引数に Optional が付いているときは省略できます。

Sub 実行()
    Call サブ(引数1:=1)    ' OK
    Call サブ(引数1:=1, 2) ' エラー、省略はできても指定するには名前が必要
End Sub

' この関数を呼び出します。
Sub サブ(引数1 As String, Optional 引数2 As String = "2")

End Sub

名前を付ける理由

省略可能な引数が多くのある関数で、必要な引数だけに値を渡すためです。

Sub 実行()
    Call サブ(, , , , 5, , , , ,10) ' 何の引数なのかわかりずらい
    Call サブ(引数5:=5, 引数10:=10)  ' 引数の名前でよくわかる
End Sub

もう一つは Boolean の引数の意味を明確にするためです。

Sub 実行()
    Call サブ(True)        ' 何が True なのかわかりずらい
    Call サブ(許可:=True)  ' 許可することが名前でよくわかる
End Sub

このように Optional が付いていると省略できるので、Optional と一緒に使われます。

わざわざすべての引数に名前を付けて渡す必要はありません。基本は渡したい引数だけに値を渡すために名前を指定します。