Developer

【ExcelVBA】Functionプロシージャ(引数と戻り値)
2021.04.30
Lv1

【ExcelVBA】Functionプロシージャ(引数と戻り値)

Functionプロシージャ(引数と戻り値)

プロシージャは「Sub」から始まるものと「Function」から始まるものの2種類があります。
これまでは「Sub」から始まるSubプロシージャだけを使ってきましたが、今回はFunctionプロシージャについて紹介します。

SubプロシージャとFunctionプロシージャの違い

2つの違いは明瞭で、プロシージャの戻り値があるかないかです。

上図のように戻り値のないものがSubプロシージャ、あるものがFunctionプロシージャになります。
少し理解しにくいところとしては、どのようにこの2種を使い分ければいいのかということかと思います。簡単な判断ポイントはなく、実はどちらの仕組みを使っても同じプログラムを作ることは可能なことが多いです。

では、同じ処理のプログラムを2種で作ってみるとどうなるかを見てみましょう。
今回サンプルとしたのは、前回サンプルとして作成した「f(x)=2x+1」を行うプロシージャです。
その例にさらに呼び出し元のプログラムを作成してみました。呼び出し元(上のプロシージャ)では、1から5まで5回ループしてf(x)の計算結果をイミディエイトウィンドウへ出力するようになっています。

まずは、Functionプロシージャつまり戻り値を使用するケースです。

Sub VBA基礎第20回_1()
    Dim i As Integer
    Dim x As Integer
    
    For i = 1 To 5

        x = f(i)
        Debug.Print x
        
    Next
    
    MsgBox "完了", vbInformation
    
End Sub

Function f(i As Integer) As Integer

    f = i * 2 + 1
    
End Function

7行目でFunctionプロシージャを呼び出しています。Subプロシージャの場合はCall命令を使用しましたが、戻り値があるようなFunctionプロシージャではこのように変数への代入式の右辺として利用されるケースが多いです。f(i)の実行結果が変数xに代入されます。
イメージしにくい方は前回と同様にステップ実行をしてみるといいかと思います。
fプロシージャでは、2倍してプラス1する処理を行いそれを「f」に代入しています。「f」すなわちプロシージャ名に値を代入することで、その値が戻り値となる仕組みとなっています。
また、Functionプロシージャ定義の最後に「As Integer」を付ける必要があります。これは戻り値のデータ型を指定します。

次に、Subプロシージャつまり戻り値を使わないケースです。

Sub VBA基礎第20回_2()
    Dim i As Integer
    Dim x As Integer
    
    For i = 1 To 5

        Call s(i)
        
    Next
    
    MsgBox "完了", vbInformation
    
End Sub

Sub s(i As Integer)
    Dim x As Integer

    x = i * 2 + 1
    Debug.Print x
    
End Sub

まずは、7行目が変わっています。プロシージャを呼び出し部分をFunctionからSubに変更する必要があるため、Call命令を使う記述に変わりました。戻り値がありませんので変数に代入することはできません。
一方で、18、19行目を見てみましょう。Functionの場合と違い計算結果を一次的に「x」に代入した後、「Debug.Print」命令でイミディエイトウィンドウへ出力しています。

今回のサンプルプログラムで行わなくてはいけない処理は以下の通りです。
この4つの処理は必ずどこかで行わなくてはいけません。

・1~5までループする
・ループカウンタを2倍してプラス1する
・計算結果を出力する
・完了メッセージを表示する

「結果を出力する」という部分がFunctionの場合とSubの場合で、呼び出し元と呼び出し先のどちらで行うのかが変わっています。
Subの場合は戻り値を使えないため、計算結果を呼び出し元に返すことができないということですね。

前述の通りどちらが正しいということはありません。
ただし、1つの観点としては、前回「1つのプロシージャは1つの機能に特化させることが望ましい」とありましたので、今回のSubプロシージャの例のように2つの処理「2x+1を計算する」と「計算結果を出力する」とするよりは出力する部分はなくし計算のみに特化させた方がベターと考えることもできます。

まとめ

VBAのプロシージャはFunctionプロシージャとSubプロシージャの2種類にわけることができる。
Functionプロシージャは戻り値を持つことができ、Subプロシージャは持たせることができない。

確認問題

以下の「○○○」に当てはまる文言を解答してください。

○○○プロシージャは戻り値を持つことができ、○○○プロシージャは持たせることができない。
戻り値を設定するには次のように行う。

Function sample(i As Integer) As Integer

    ○○○ = i * 2 + 1
    
End Function
答え

Functionプロシージャは戻り値を持つことができ、Subプロシージャは持たせることができない。
戻り値を設定するには次のように行う。
[vb] Function sample(i As Integer) As Integer

sample = i * 2 + 1

End Function
[/vb]

次回は、プロシージャの引数です。

 
 

連載目次リンク

ExcelVBA 入門 連載目次