はじめに
ExcelVBAでSubプロシージャやFunctionプロシージャを作るとき、「引数はいつも同じ値を渡すことが多いけど、たまに変えたい」というケースはよくあります。そんなときに便利なのがOptional引数です。
Optional引数を使うと、引数を省略しても動くプロシージャを作ることができ、呼び出し側のコードがシンプルになります。この記事では、Optional引数の基本的な書き方から、デフォルト値の指定方法、IsMissing関数との組み合わせ、実務でよく使う活用例までを解説します。
Optional引数とは
Optional引数とは、プロシージャを呼び出すときに省略してもエラーにならない引数のことです。通常の引数(必須引数)は呼び出し時に必ず値を渡す必要がありますが、Optional引数を使えば、値を渡さなかった場合はあらかじめ設定した既定値が使われます。
基本的な構文は以下の通りです。
Sub プロシージャ名(Optional 引数名 As データ型 = 既定値)
' 処理内容
End Sub
Optionalキーワードを引数の前に付け、=のあとに省略時のデフォルト値を指定します。
基本的な使い方
まずはシンプルな例で確認してみましょう。以下は、挨拶文を表示するマクロです。名前を省略した場合は「ゲスト」として扱います。
Sub ShowGreeting(Optional ByVal userName As String = "ゲスト")
MsgBox userName & "さん、こんにちは!"
End Sub
Sub CallSample()
Call ShowGreeting("田中") ' 「田中さん、こんにちは!」
Call ShowGreeting ' 「ゲストさん、こんにちは!」
End Sub
ShowGreetingを引数なしで呼び出すと、userNameには自動的に「ゲスト」が入ります。呼び出し側で毎回同じ値を書く必要がなくなるため、コードがすっきりします。
複数のOptional引数を使う
Optional引数は複数指定することもできます。ただし、必須引数は必ずOptional引数より前に書くというルールがあります。
Sub InsertData(ByVal targetSheet As String, _
Optional ByVal startRow As Long = 2, _
Optional ByVal startCol As Long = 1)
Dim ws As Worksheet
Set ws = ThisWorkbook.Worksheets(targetSheet)
ws.Cells(startRow, startCol).Value = "サンプルデータ"
End Sub
Sub CallInsertData()
Call InsertData("Sheet1") ' 2行1列目に入力
Call InsertData("Sheet1", 5) ' 5行1列目に入力
Call InsertData("Sheet1", 5, 3) ' 5行3列目に入力
End Sub
このように、途中の引数から省略していくことで、必要な部分だけを柔軟に指定できます。
IsMissing関数で「省略されたかどうか」を判定する
デフォルト値を設定する方法とは別に、IsMissing関数を使うと「その引数が省略されたかどうか」を明示的に判定できます。ただしIsMissingは引数のデータ型がVariantの場合のみ使える点に注意してください。
Sub CheckArgument(Optional ByVal targetDate As Variant)
If IsMissing(targetDate) Then
MsgBox "日付が省略されたので、今日の日付を使用します。" & vbCrLf & Date
Else
MsgBox "指定された日付:" & targetDate
End If
End Sub
デフォルト値では対応できない「省略されたこと自体を判定して処理を分岐したい」場合に有効な方法です。
実務での活用例:ログ出力プロシージャ
Optional引数は、ログ出力のような「毎回は指定しないが、必要なときだけ変更したい」処理と相性が良いです。以下は、シートにログを1行追記するプロシージャの例です。
Sub WriteLog(ByVal message As String, _
Optional ByVal logSheetName As String = "Log", _
Optional ByVal includeTimestamp As Boolean = True)
Dim ws As Worksheet
Dim nextRow As Long
Set ws = ThisWorkbook.Worksheets(logSheetName)
nextRow = ws.Cells(ws.Rows.Count, 1).End(xlUp).Row + 1
If includeTimestamp Then
ws.Cells(nextRow, 1).Value = Format(Now, "yyyy/mm/dd hh:nn:ss")
ws.Cells(nextRow, 2).Value = message
Else
ws.Cells(nextRow, 1).Value = message
End If
End Sub
Sub SampleUsage()
Call WriteLog("処理を開始しました")
Call WriteLog("エラーが発生しました", "ErrorLog")
Call WriteLog("タイムスタンプなしのログ", "Log", False)
End Sub
このように、通常は既定の設定で呼び出しつつ、特殊なケースだけ引数を指定するという使い方ができ、呼び出し元のコードが読みやすくなります。
注意点
Optional引数を使う際は、以下の点に注意してください。
- Optional引数は、引数リストの後方にまとめて配置する必要があります(必須引数の後)
- デフォルト値には、定数や固定値のみ指定可能です(他の変数の値を初期値にはできません)
- 型を
VariantにするとIsMissingが使えますが、それ以外の型(String、Long等)ではIsMissingは常にFalseを返すため注意が必要です
まとめ
この記事では、ExcelVBAのOptional引数について解説しました。
Optionalキーワードとデフォルト値を使うことで、引数を省略できるプロシージャが作れる- 複数のOptional引数を使う場合は、必須引数を先に書く
IsMissing関数を使えば、Variant型の引数に限り「省略されたかどうか」を判定できる- ログ出力など「基本は同じ設定・たまに変更したい」処理と相性が良い
Optional引数をうまく活用すると、呼び出し側のコードが簡潔になり、再利用性の高いプロシージャを作ることができます。ぜひ自分のマクロにも取り入れてみてください。


コメント