Excel VBAには、SubプロシージャのほかにFunctionプロシージャというものがある。このページではFunctionプロシージャに焦点を当てて説明する。また、エキスパート試験で問われそうな内容についても、合わせて解説する。
Functionプロシージャは値を返す
SubプロシージャとFunctionプロシージャは、次の点で異なる。
- Subプロシージャ ⇒ 値(結果)を返さない
- Functionプロシージャ ⇒ 値(結果)を返す
少し説明を加える。
次のサンプルコードAは、Subプロシージャの例だ。Subプロシージャ「Test1」を実行すると、内部で別のSubプロシージャ「Test2」が呼び出される。その結果、メッセージボックスに「Test2を呼び出しました」と表示される。
◆ サンプルコードA
Sub Test1()
Call Test2
End Sub
Sub Test2()
MsgBox "Test2を呼び出しました"
End Sub
次のサンプルコードBは、Functionプロシージャの例だ。Subプロシージャ「Test1」とFunctionプロシージャ「Test2」が定義されている。「Test1」を実行すると、メッセージボックスに「Test2を呼び出しました」と表示される。
◆ サンプルコードB
Sub Test1()
Dim str As String
str = Test2
MsgBox str
End Sub
Function Test2() As String
Test2 = "Test2を呼び出しました"
End Function
実行結果は同じですが、処理の流れは異なる。先に述べたサンプルコードAのほうは、プロシージャ「Test2」の中でMsgBox関数を実行している。それに対して、サンプルコードBのほうはプロシージャ「Test1」の中でMsgBox関数を実行している。
◆ サンプルコードA(「Test2」の中でMsgBox関数を実行)
Sub Test1()
Call Test2
End Sub
Sub Test2()
MsgBox "Test2を呼び出しました"
End Sub
◆ サンプルコードB(「Test1」の中でMsgBox関数を実行)
Sub Test1()
Dim str As String
str = Test2
MsgBox str
End Sub
Function Test2() As String
Test2 = "Test2を呼び出しました"
End Function
サンプルコードBのプロシージャ「Test2」はFunctionプロシージャだ。このプロシージャは、「Test2を呼び出しました」という文字列を呼び出し元に返す。呼び出し元というのは、プロシージャ「Test1」だ。返した文字列は変数Strに格納され、メッセージボックスに表示される。
◆ サンプルコードBの流れ
それに対して、Subプロシージャは値を返すことができない。よって、次のように書くとコンパイルエラーが発生する。
Sub Test1()
Dim str As String
str = Test2
MsgBox str
End Sub
Sub Test2() As String 'コンパイルエラー
Test2 = "Test2を呼び出しました"
End Sub
VBAエキスパート試験でおさえておきたいポイント
Functionプロシージャは値を返さなくてもいい
functionプロシージャは値を返すことができるが、あえて返さなくても問題ない。
たとえば、次のように書くことが可能だ。
Sub Test1()
Call Test2
End Sub
Function Test2()
MsgBox "Test2を呼び出しました"
'何も値を返さない
End Function
Subプロシージャ「Test1」を実行すると、Functionプロシージャ「Test2」が呼ばれる。そしてメッセージボックスが表示される。しかし、プロシージャ「Test2」は何の値も返さない。それでもコンパイルエラーは発生せず、正常にコードを実行することができる。
この例を見て分かるとおり、Functionプロシージャは値を返さなければSubプロシージャと同じ結果となる。ただし、実用性はないと思う。「こういう書き方もできるんだ」ということを、エキスパート試験対策として覚えておけばいいだろう。
FunctionプロシージャもCallステートメントで呼べる
Functionプロシージャは、Subプロシージャと同じようにCallステートメントで呼ぶことが可能だ。次のコードは正常に動作する。
Sub Test1()
'Callステートメントで呼べる
Call Test2
End Sub
Function Test2()
MsgBox "Test2を呼び出しました"
End Function
ただし戻り値を受け取りたい場合は、Callステートメントを使うことはできない。次のコードはエラーになる。
Sub Test1()
Dim str As String
Call str = Test2 'コンパイルエラー
MsgBox str
End Sub
Function Test2() As String
Test2 = "Test2を呼び出しました"
End Function
練習問題
- Functionプロシージャは値を返すことができる。
- FunctionプロシージャをCallステートメントで呼びだすことはできない。
- Functionプロシージャには必ず引数を定義しなければならない。
- Functionプロシージャは「Function プロシージャ名()」で始まり「End Function」で終わる。
正解を見る
コメント