Kの備忘録(仮)

Python、VBA、Excelを中心に記事を投稿

VBA 戻り値の有無の処理の違いについて(引数ありSubプロシージャとFunctionプロシージャで比較)

はじめに

戻り値があることで、どんな利点があるのかを調べてみました。
VBAの場合を例に、「引数ありSubプロシージャ」と「Functionプロシージャ」で比較したいと思います。
※あくまでこの記事は、「戻り値の有無の比較」がメインとなります。

◆目次◆

登場する用語

  • 引数
    関数に代入する値

  • 戻り値
    関数の処理結果

なお、戻り値ありのプロシージャは以下のように記述します。

Function Functionプロシージャ名(引数名 As データ型) As 戻り値のデータ型

    Functionプロシージャ名 = 戻り値

End Function

戻り値の有無の処理の違いについて

  • 戻り値がある場合
    「同じ処理をしたいが、場所によって異なる引数を値に代入したい」
    というマクロを作成できます。

  • 戻り値がない場合
    引数が異なる場合は、同じ処理でもその都度処理を明記する必要があります。

なお、戻り値の有無は、VBAの場合、プロシージャの種類によって決まります。

プロシージャの種類

  • Subプロシージャ
    戻り値なしの処理を行うプロシージャ

  • Functionプロシージャ
    戻り値ありの処理を行うプロシージャ

なお、「引数なしFunctionプロシージャ」や「戻り値なしFunctionプロシージャ」も作成可能ですが、今回は省略します。

以降は「Functionプロシージャ」=「引数あり戻り値ありFunctionプロシージャ」と読みかえてください。

引数ありSubプロシージャとFunctionプロシージャの比較

では、戻り値の有無でどのような違いがあるのか見ていきたいと思います。

比較のため、例として
「「セルA1」、「セルB2」、「セルC3」に、変数xと変数yを足した値を表示する」
というマクロを、以下のプロシージャ使って作成します。

  • 引数なしSubプロシージャ
  • 引数ありSubプロシージャ
  • Functionプロシージャ

引数なしSubプロシージャ

このプロシージャだけで処理を行います。
(上から順番に処理をするのみ)

' 引数なしSubプロシージャ
Sub sub_add1()

    Dim x As Long
    Dim y As Long
    
    x = 5
    y = 10
    
    Range("A1").Value = x + y
    Range("B2").Value = x + y
    Range("C3").Value = x + y

End Sub

引数ありSubプロシージャ

引数ありのプロシージャを使用するときは、セットで呼び出し用のプロシージャが必要です。
引数ありSubプロシージャで処理を行い、呼び出し用のプロシージャで引数の値を設定します。

なお、Subプロシージャを呼び出すときは、Callステートメントを使用します。

書き方は、「Call」を明記する方法と、「Call」を明記しない方法があります。
個人的には、「Call」を明記した方が「Subプロシージャを呼び出している」ということがわかりやすい(可読性が高い)ため、「Call」を明記した方が良いと思います。

' 引数ありSubプロシージャの呼び出し(「Call」を明記した場合)

Sub sub_add2_1()
    
   Call sub_add2_3(5, 10)

End Sub
' 引数ありSubプロシージャの呼び出し(「Call」を明記しない場合)
Sub sub_add2_2()
    
    sub_add2_3 5, 10
  
End Sub
' 引数ありSubプロシージャ
Sub sub_add2_3(x As Long, y As Long)
    
    Range("A1").Value = x + y
    Range("B2").Value = x + y
    Range("C3").Value = x + y

End Sub

Functionプロシージャ

Functionプロシージャを使用するときは、セットで呼び出し用のプロシージャが必要です。
Functionプロシージャで処理を行い戻り値を返し、呼び出し用のプロシージャで戻り値の処理と、引数の値を設定します。

なお、引数ありFunctionプロシージャを呼び出すときは、Callステートメントを使用しません。
(引数なしFunctionプロシージャの呼び出すときは、Callステートメントを使用します)

' 引数ありFunctionプロシージャの呼び出し
Sub func_add1_1()
    
  Range("A1").Value = func_add1_2(5, 10)
  Range("B2").Value = func_add1_2(5, 10)
  Range("C3").Value = func_add1_2(5, 10)

End Sub
' 引数ありFunctionプロシージャ
Function func_add1_2(x As Long, y As Long) As Long

    func_add1_2 = x + y

End Function

Functionプロシージャの使いどころ

複数の箇所で、異なる引数を代入して、同じ処理(計算など)を行いたい ときに便利です。

たとえば、上記のFunctionプロシージャのコードを例にすると 「セルA1」、「セルB2」、「セルC3」で引数を変えたいときは以下のように修正すれば良いので、保守性が高いと言えます。

' 引数ありFunctionプロシージャの呼び出し
Sub func_add1_1()
    
  Range("A1").Value = func_add1_2(5, 10)
  Range("B2").Value = func_add1_2(6, 10)
  Range("C3").Value = func_add1_2(7, 10)

End Sub
' 引数ありFunctionプロシージャ
Function func_add1_2(x As Long, y As Long) As Long

    func_add1_2 = x + y

End Function

戻り値があることの利点

繰り返しになりますが、戻り値があると 複数の箇所で、異なる引数を代入して、同じ処理(計算など)を行うことができます
逆に、戻り値がない場合は、その都度処理を明記しなければならないため、保守性と可読性が低くなります。

完成したマクロでも時間がたてば補修が必要になることは多々あります。
保守性と可読性が高いマクロを最初から作成しておけば、マクロの補修も楽です。

Functionプロシージャをうまく活用できれば、保守性と可読性が高いマクロを作成することができるので、使わない手はないですね。