ExcelとAccessのスキルアップをサポートするサイトです

ExcelとAccessの学習室

SUBプロシージャとFunctionプロシージャの違い(VBA)

このような疑問を感じたことはありませんか?

「SubプロシージャとFunctionプロシージャっていったいどこが違うの?本やネットでも難しい説明しかされていないし。」

いろんなサイトで説明されているのを見ますが、納得できるものって少ないですよね?

この記事を書いている私は、約10年前からVBAを使い始め、社内の業務改善をしてきました。

これまでにもいくつかの壁にもぶつかってきました。

そのうちの一つが、「SubプロシージャとFunctionプロシージャの違い」です。

セミナーでFunctionプロシージャというものがあることを知り、使いこなせるようになりたくて学習してきましたが、ずっと解決できませんでした

しかし、最近になってようやく両者の違いを理解するコツが分かってきました

今回紹介する方法を試せれば、しっかりとFunctionを理解出来ると思います。

Functionを理解出来れば、VBAスキルも更に高められます。

まだFunctionを使いこなせていない方は、是非この記事を読んで頂きたいです。

一般的に言われているSubとFunctionの違い

まずは、いろんなサイトで書かれているSubと Functionの違いについて触れます。

種類単独使用戻り値
Subプロシージャ使用できる返せない
Funtionプロシージャ使用できない返せる

一般的に一覧表のようなことが言われています。

単独で使えるかどうか

Subプロシージャはマクロ記録などを行った時に作成されるもので、単独で使うことができません。

マクロを作る時に、最もよく使われるプロシージャです。

一方、Functionは単独で使うことが出来ません。

Sub test1() 'Subプロシージャはボタンに登録できる
    MsgBox ("test1です")
End Sub

Function test2() 'Functionプロシージャはボタンに登録できない
    MsgBox ("test2です")
End Function

上のコードは同じ命令をSubとFunctionにしたものですが、ステップインでは両方とも作動します。

ところが、ワークシートにボタンを作り、マクロを登録してみます。

Subであるtest1は表示されていますが、Functionであるtest2は表示されません。

戻り値を返せるか

Functionプロシージャは戻り値を返せます。

一方、Subプロシージャは戻り値を返せません。

戻り値とは、マクロを実行することで得られた値を呼び出し元に戻すということです。

戻り値の説明には、上のようなイメージのイラストがよく使われます。

確実にSubとFunctionの違いを知るには手を動かせ

また、Functionプロシージャは戻り値を設定しなくても普通に作動します。

SubとFunctionの境目がわかりづらい理由です。

では、SubとFunctionの違いをどうやって理解するか。

それは、「CALL文を作ってSubとFunctionを書き換えてみる」ことです。

'Subでも動くパターン
Sub Calling_Msg1()
    Call msg1("これはテストです。")
End Sub

Sub msg1(ByVal msstring As String)
    MsgBox (msstring)
End Sub

上のパターンの場合、msg1プロシージャはSubでもFunctionでも正常に動きます。

'Functonしか動かないパターン
Sub Calling_Msg2()
    Call MsgBox(msg2("これは"))
End Sub

Function msg2(ByVal msstring As String)
    msg2 = msstring & "テストです。"
End Function

一方、Functionしか作動しないのは上のパターンです。

msg2のFunctionをSubに書き換えた場合、このようなエラーが発生します。

まさにFunctionしか使えない、戻り値を返すプログラムが出来上がっています

Functionで正常に動くけど、Subではエラー停止するCALL文

このようなCALL文をさがしてみることが、戻り値を理解する一番の近道です。

戻り値が理解できれば、SubとFunctionの違いも分かってきます。

文字列や数値など、いろいろなデータを使ってテストしてみましょう。

参考までに、数値を戻り値にしたコードも添付しておきます。

コピペして実際に中身をいろいろ変えてみましょう。

'subでも動く
Sub Calling_Msg3()
    Call msg3(100)
End Sub

Sub msg3(ByVal n1 As Long)
    msg3 = MsgBox(Len(CStr(n1)) & "桁の整数です")
End Sub

'Functionしか動かない
Sub Calling_Msg4()
    Call MsgBox(msg4(100) & "桁の整数です")
End Sub

Function msg4(n2 As Long)
    msg4 = Len(CStr(n2))
End Function

Functionはワークシート関数を自作出来る

Functionプロシージャを使えば、独自のワークシート関数を作ることが出来ます。

Subプロシージャには無い機能です。

関数を作る時は、引数に必ずセル範囲(Range型)を設定します。

Long型やString型は、エラーになってしまうので自作関数では使えません。

Function DIVIDE(r1 As Range, r2 As Range)
    '除算ゼロエラーを出さないための自作関数
    If r2 = 0 Then
        DIVIDE = 0
    Else
        DIVIDE = r1 / r2
    End If
End Function

上のコードは、除算ゼロエラーを無くすために設定したものです。

セルに関数を入力してみると、コーディングした通りの計算を行なっています。

Functionを使う事で

  • Functionを使う事で
  • エラー回避できる
  • 関数の引数を少なくできる
  • 複数の関数を一つにまとめる

という、オリジナルの関数を作る事ができますので、是非試してみてくださいね。

まとめ

今回は、SubプロシージャとFunctionプロシージャの違いについて解説しました。

両者の違いだけでなく、Functionの機能を学習できれば、更にVBAプログラミングのレベルが向上します。

そのためにも、手を動かして少しずつコードを変更してみるのが一番の近道です。

一つ一つ調べるのは大変ですが、その時にかけた時間は後で必ず活きてきますので、試してみてください。


本日もありがとうございました。