Excel VBA | 超初心者(Excel操作+マクロ体験):VBA基礎環境 – SubとFunctionの違い

Excel VBA VBA
スポンサーリンク

まずざっくり:「Sub」と「Function」の一番大きな違い

一言で言うと、こうです。

Sub
「何か処理をするだけの手順」
結果(値)を“返さない”タイプのプロシージャ

Function
「何か処理をして、その結果を“値として返す”手順」
関数として値を返すプロシージャ

ここが本質です。
「値を返すかどうか」――この一点だけで、Sub と Function を見分けられるようになると、かなりスッキリします。


Subとは何か:結果を返さない「手順」

Subの役割をイメージでつかむ

Sub は、「これをやって」「あれもやって」と、Excelに対して命令を並べた“作業手順”です。
実行すると、セルを書き換えたり、メッセージを出したり、シートをコピーしたりしますが、
「この値を返します」という形では結果を返しません。

Excel側から見ると、
「呼び出したら何かしてくれるけど、値としては何ももらわない」
そんな“お仕事係”が Sub です。

Subの基本形

形はこうです。

Sub プロシージャ名()

    ' ここに処理を書く

End Sub
VB

例として、メッセージを出すだけの Sub を書いてみます。

Sub あいさつ()

    MsgBox "こんにちは!"

End Sub
VB

この Sub を実行すると、メッセージボックスが出るだけで、
「戻り値」というものはありません。

典型的なSubの使いどころ

例えば、次のような処理は、ほとんど Sub で書きます。

・セルに値を書き込む
・書式を整える
・シートを追加・削除する
・ファイルを開く・保存する
・ボタンを押したときに一連の処理を行う

「Excelの状態を変えること自体が目的」のときは、Sub がしっくりきます。


Functionとは何か:値を返す「関数」

Functionの役割をイメージでつかむ

Function は、「何かを計算して、その結果を“値として返す”」ためのプロシージャです。
Excelのワークシート関数(SUM、AVERAGE など)と同じイメージで考えると分かりやすいです。

呼び出し側から見ると、
「このFunctionを呼ぶと、計算結果が一つ“値として”返ってくる」
その値を、セルに入れたり、他の計算に使ったりできます。

Functionの基本形

形はこうです。

Function 関数名(引数...) As

    ' 計算などをして
    関数名 = 戻したい値

End Function
VB

一番大事なのは、
「Function名に値を代入することで“戻り値”を決める」
というルールです。

簡単なFunctionの例

例えば、二つの数値の合計を返す Function を作ってみます。

Function AddTwoNumbers(a As Long, b As Long) As Long

    AddTwoNumbers = a + b

End Function
VB

この Function は、呼び出すと「a + b の結果」を返します。

VBAの中からなら、こう使えます。

Sub Test()

    Dim result As Long
    result = AddTwoNumbers(10, 20)

    MsgBox result   ' 30 が表示される

End Sub
VB

ワークシートからも、ユーザー定義関数として使えます。

セルに
=AddTwoNumbers(10,20)
と入力すると、セルに 30 が表示されます。

ここが Sub との決定的な違いです。
Sub はセルに直接書き込むなど「外側を変える」のが得意で、
Function は「値を返して、呼び出し側に判断を委ねる」のが得意です。


SubとFunctionの違いを整理して深掘り

違い1:戻り値があるかどうか(最重要)

Sub
戻り値を持たない。
呼び出し側に「値として」何かを返すことはできない。

Function
戻り値を持つ。
Function名に代入した値が、そのまま戻り値になる。

この違いが、設計の分かれ目になります。
「この処理の結果を、どこかで“値として使いたい”か?」
と自分に問いかけて、Yes なら Function、No なら Sub が基本の考え方です。

違い2:ワークシートから直接呼べるか

Sub
ワークシートのセルから =Sub名() のように呼ぶことはできません。
マクロとして実行するか、他のVBAコードから呼び出します。

Function
条件を満たしていれば、ワークシート関数としてセルから呼べます。
=関数名(引数...) の形で使えるので、「自作の関数」を作るイメージです。

「セルに直接使いたい処理」は Function 一択になります。

違い3:呼び出し方の書き方

Sub を他のプロシージャから呼ぶときは、こう書きます。

Call あいさつ
' または
あいさつ
VB

Function を呼ぶときは、「値を受け取る」形で書きます。

Dim x As Long
x = AddTwoNumbers(10, 20)
VB

Sub は「命令」、Function は「値を返す式」として扱われる、という感覚です。


同じ処理をSub版とFunction版で比べてみる

例題:合計を出してメッセージに表示する

まずは Sub だけで書いたバージョンです。

Sub ShowTotal_Sub()

    Dim a As Long
    Dim b As Long
    Dim total As Long

    a = 10
    b = 20
    total = a + b

    MsgBox "合計は " & total & " です"

End Sub
VB

この Sub は、「合計を計算して、その場でメッセージを出す」までを全部自分でやっています。
戻り値はありません。

次に、「計算する部分だけ Function に切り出す」バージョンです。

Function GetTotal(a As Long, b As Long) As Long

    GetTotal = a + b

End Function

Sub ShowTotal_Function()

    Dim total As Long
    total = GetTotal(10, 20)

    MsgBox "合計は " & total & " です"

End Sub
VB

ここでは、
GetTotal が「合計を計算して値を返す役」
ShowTotal_Function が「その値をどう使うか決める役」
に分かれています。

この分け方のメリットは、
「GetTotal は、他の場所からも再利用できる」
という点です。

例えば、別の Sub からもこう呼べます。

Sub WriteTotalToCell()

    Range("A1").Value = GetTotal(5, 7)

End Sub
VB

同じ「合計を出す処理」を、メッセージに出したり、セルに書いたり、好きな形で使い回せるようになります。


いつSubで、いつFunctionにするかの判断基準

基本の問い:「結果を値として使いたいか?」

一番シンプルな判断基準はこれです。

結果を「値として」どこかに渡したいか?
Yes → Function
No(その場でセルを書き換える、メッセージを出すなどで完結) → Sub

例えば、

合計を計算して、その場でメッセージに出すだけ
→ Sub でも Function でも書けるが、Sub で完結させてもよいケースが多い。

合計を計算して、その値をセルに入れたり、別の計算に使ったりしたい
→ Function にしておくと、再利用しやすくなる。

「副作用」と「純粋な計算」を分けて考える

もう一歩踏み込むと、
「Excelの状態を変える処理(副作用)」と
「値を計算するだけの処理(純粋な計算)」
を分ける、という考え方があります。

セルを書き換える、シートを追加する、ファイルを保存する――こういうのは副作用です。
これは Sub に任せるのが基本です。

一方で、「二つの数値の合計」「税抜き金額から税込み金額を出す」などは純粋な計算です。
これは Function にしておくと、どこからでも呼び出せて、テストもしやすくなります。

超初心者のうちは、
「Excelを直接いじるのは Sub」
「計算だけなら Function にしてみる」
くらいの感覚で十分です。


まとめ:SubとFunctionを“使い分けられる人”になる

ここまでのポイントをぎゅっとまとめると、こうなります。

Sub
結果を値として返さない「手順」。
セル操作や画面表示など、「Excelの状態を変える処理」をまとめるのに向いている。

Function
結果を値として返す「関数」。
計算結果や判定結果を返し、それを呼び出し側で自由に使える。
ワークシート関数としてセルからも呼べる。

次の練習としておすすめなのは、こんな流れです。

1つ目:今まで Sub だけで書いていた「合計を出す処理」を、Function に切り出してみる。
2つ目:その Function を、メッセージ表示用の Sub と、セル書き込み用の Sub の両方から呼んでみる。
3つ目:余裕があれば、その Function をワークシートから =関数名() で呼んでみる。

「処理を“値を返す関数”として切り出せるようになる」と、コードの組み立て方のレベルが一段上がります。

タイトルとURLをコピーしました