構文


[適用範囲]1 [Static]2 Sub プロシージャ名3([引数]4)
    [処理]12
End Sub

1 - [適用範囲] ----- (省略可) Public、Private、Friendのいずれかを指定します。省略するとPublicが指定されたとみなされます。
2 - [Static] ----- (省略可) 指定すると、ローカル変数の値が保持されます。
3 - プロシージャ名 ----- プロシージャ名を指定します。
4 - [引数] ----- (省略可) プロシージャに渡される値を受け取るための変数を指定します。「,」で区切って複数指定することができます。
引数を指定する方法は次の通りです。

[Optional]5 [値の渡し方]6 [ParamArray]7 引数名8[()]9 [As 型]10 = 規定値11

5 - [Optional] ----- (省略可) 指定した引数は、値の受け取りを省略できます。
6 - [値の渡し方] ----- (省略可) ByVal、または、ByRefを指定します。省略するとByRefが指定されたとみなされます。
7 - [ParamArray] ----- (省略可) 指定すると、任意の数の値を受け取ることができます。
8 - [引数名] ----- (省略可) 値を受け取る変数名を指定します。
9 - [()] ----- (省略可) 指定すると、配列を受け取ることができます。
10 - [As 型] ----- (省略可) 変数の型を指定します。省略するとVariant型となります。
指定できる値は次の通りです。

11 - [規定値] ----- (省略可) Optionalキーワードを指定した引数の値が省略された場合の、規定値を指定します。
12 - [処理] ----- (省略可) 処理を指定します。

解説


Subプロシージャを定義します。

適用範囲1に、Publicキーワードを指定するか、指定を省略して宣言すると、
そのプロジェクト内にあるすべてのモジュールのすべてのプロシージャから呼び出すことができます。
適用範囲1に、Privateキーワードを指定して宣言すると、
そのモジュール内にあるすべてのプロシージャから参照できます。別のモジュールにあるプロシージャからは呼び出すことができません。
適用範囲1に、Friendキーワードを指定して宣言すると、
そのプロジェクト内にあるすべてのモジュールのすべてのプロシージャから呼び出すことができます。外部のプロジェクトからは呼び出すことができません。
Friendキーワードは、クラスモジュールで使用します。

Static2キーワードを指定して宣言すると、
プロシージャが終了した後も、ローカル変数(プロシージャ内で定義された変数)の値が保持されます。

プロシージャ名3や、引数名8は自由に決められますが、以下のようなルールがあります。
・使用できる文字は、英数字(全角半角)、漢字、ひらがな、カタカナ、記号は_のみ。
・先頭文字は、英字か漢字、ひらがな、カタカナ。
・キーワードや予約語と呼ばれるVBAが使用する語と同じ名前は使えない など

値の渡し方6に、ByValキーワードを指定すると、変数が「値渡し」となります。
値渡し」とは、呼び出し元のプロシージャから、呼び出し先のプロシージャへ、変数に格納されている値をコピーして渡す方法です。
値をコピーして渡すため、呼び出し先で値の変更が行われても、呼び出し元の値には影響しません。
変数を箱と考えるなら、箱の中身と同じものを相手に渡す、というイメージです。
値の渡し方6に、ByRefキーワードを指定するか、指定を省略すると、変数が「参照渡し」となります。
参照渡し」とは、呼び出し元のプロシージャから、呼び出し先のプロシージャへ、変数自体を渡す方法です。
変数を渡すため、呼び出し先で変数に格納されている値の変更が行われると、呼び出し元で参照している同じ変数には、変更後の値が格納されていることになります。
変数を箱と考えるなら、同じ箱を相手と使う(参照する)、というイメージです。

Optional5キーワードを指定すると、それ以降の引数にも、Optionalキーワードを指定しなければなりません。
また、ParamArrayキーワードと併用することはできません。

ParamArray7キーワードは、最後の引数で、かつ、Variant型配列のみ指定することができます。

VBAコード


---------- モジュール「Module1」 ---------- Sub Sample1() Dim Num1 As Long Dim Num2 As Long Dim Num3(2) As String Num1 = 0 Num2 = 50 Num3(0) = "A": Num3(1) = "B": Num3(2) = "C" Call NumCounter(Num1, Num2, Num3) MsgBox "Num1=" & Num1 & ", Num2=" & Num2 Call CheckPoint Call TextMessage("Hello!") Call CheckPoint Call CellText(1, "ABC", 1, 2, 3) End Sub Sub Sample2() Call Module2PrivateSub End Sub Sub Sample3() Dim c As Class1 Set c = New Class1 c.SaveWorkbook ThisWorkbook Set c = Nothing End Sub Static Sub CheckPoint() Dim Cnt As Long Cnt = Cnt + 1 Debug.Print "CheckPoint " & Cnt End Sub Sub NumCounter(Num1 As Long, ByVal Num2 As Long, Num3() As String) Num1 = Num1 + 1 Num2 = Num2 + 1 MsgBox "Num1=" & Num1 & ", Num2=" & Num2 & vbCrLf & _ "Num3(0)=" & Num3(0) & ", Num3(1)=" & Num3(1) & ", Num3(2)=" & Num3(2) End Sub Sub TextMessage(Str1 As String, Optional Str2 As String = " Excel", Optional Str3 As String) MsgBox Str1 & Str2 & Str3 End Sub ---------- モジュール「Module2」 ---------- Public Sub CellText(lRow As Long, sText As String, ParamArray lCol() As Variant) Dim i As Variant For Each i In lCol Worksheets("Sheet1").Cells(lRow, CInt(i)).Value = sText Next End Sub Private Sub Module2PrivateSub() Debug.Print "Sample2" End Sub ---------- モジュール「Class1」 ---------- Friend Sub SaveWorkbook(wb As Workbook) wb.Save MsgBox "保存しました。" End Sub

実行


---------- モジュール「Module1」 ----------
ExcelVBA

Call NumCounter(Num1, Num2, Num3)
プロシージャ「NumCounter」に処理が移ります。
Sub NumCounter(Num1 As Long, ByVal Num2 As Long, Num3() As String)
引数「Num1」は「参照渡し」、引数「Num2」は「値渡し」、配列引数「Num3」は「参照渡し」で値を受け取ります。
Num1 = Num1 + 1
Num2 = Num2 + 1
引数「Num1」と、引数「Num2」の値に、それぞれ「1」を加算します。
MsgBox "Num1=" & Num1 & ", Num2=" & Num2 & vbCrLf & _
"Num3(0)=" & Num3(0) & ", Num3(1)=" & Num3(1) & ", Num3(2)=" & Num3(2)
ExcelVBA
ここでは、引数「Num1」の値が「1」、引数「Num2」の値が「51」です。
呼び出し元に処理が移ります。
MsgBox "Num1=" & Num1 & ", Num2=" & Num2
ExcelVBA
変数「Num1」の値は「1」、変数「Num2」の値は「50」です。
変数「Num2」の値は、プロシージャ「NumCounter」に「値渡し」で値を渡したため、呼び出し先プロシージャ内での計算結果の影響を受けません。

Call CheckPoint
プロシージャ「CheckPoint」に処理が移ります。
Static Sub CheckPoint()
プロシージャ「CheckPoint」は、Staticキーワードが指定されているため、プロシージャが終了した後も、ローカル変数の値が保持されます。
Dim Cnt As Long
Long型の変数「Cnt」を宣言しています。
Cnt = Cnt + 1
Debug.Print "CheckPoint " & Cnt
ExcelVBA
変数「Cnt」の値「1」がイミディエイトウィンドウに表示されます。

Call TextMessage("Hello!")
プロシージャ「TextMessage」に処理が移ります。
Sub TextMessage(Str1 As String, Optional Str2 As String = " Excel", Optional Str3 As String)
引数「Str2」と、引数「Str3」には、Optionalキーワードが指定されているため、値の受け取りを省略できます。
引数「Str2」には、規定値として、文字列「 Excel」が指定されています。
この例では、呼び出し元で、引数「Str2」と、引数「Str3」に渡す値が省略されています。
MsgBox Str1 & Str2 & Str3
ExcelVBA
引数「Str1」の値と、規定値「 Excel」が表示されます。

Call CheckPoint
プロシージャ「CheckPoint」に処理が移ります。
Static Sub CheckPoint()
Cnt = Cnt + 1
Debug.Print "CheckPoint " & Cnt
ExcelVBA
変数「Cnt」の値がイミディエイトウィンドウに表示されます。
ローカル変数「Cnt」の値は、プロシージャが終了した後も保持されているため、「2」となります。

Call CellText(1, "ABC", 1, 2, 3)
プロシージャ「CellText」に処理が移ります。

---------- モジュール「Module2」 ----------
ExcelVBA

Public Sub CellText(lRow As Long, sText As String, ParamArray lCol() As Variant)
プロシージャ「CellText」は、Publicキーワードが指定されているため、プロジェクト内にあるすべてのモジュールのすべてのプロシージャから呼び出すことができます。
配列「lCol」には、ParamArrayキーワードが指定されているため、任意の数の値を受け取ることができます。
この例の場合、引数「lRow」には「1」、引数「sText」には「ABC」、配列「lCol」には「1」と「2」と「3」が渡されます。
For Each i In lCol
Worksheets("Sheet1").Cells(lRow, CInt(i)).Value = sText
Next
ExcelVBA
セルA1、セルB1、セルC1に、文字列「ABC」が表示されます。

Private Sub Module2PrivateSub()
プロシージャ「Module2PrivateSub」は、Privateキーワードが指定されているため、別のモジュールにあるプロシージャから呼び出すことができません。

---------- モジュール「Module1」 ----------
ExcelVBA

Call Module2PrivateSub
ExcelVBA

Set c = New Class1
c.SaveWorkbook ThisWorkbook
プロシージャ「SaveWorkbook」に処理が移ります。

---------- モジュール「Class1」 ----------
ExcelVBA

Friend Sub SaveWorkbook(wb As Workbook)
プロシージャ「SaveWorkbook」は、Friendキーワードが指定されているため、外部のプロジェクトからは呼び出すことができません。
MsgBox "保存しました。"
ExcelVBA

関連するVBA


FunctionPropertyCall