Table of Contents
FunctionとSubって何が違うの?戻り値の有無で違いがある
Excel(エクセル)でVBAを使ってマクロを作る場合、必ず目にするものがFunctionとSubではないでしょうか?
FunctionとSubはとても似ていますが、似ているからこそ正しい使い方を理解できていない人もいます。
ちなみにFunctionとSubのことをプロシージャと呼び、複数の処理を一つにまとめたものになります。
どちらも処理をまとめて定義しているだけなので、ほとんど同じ動きをしてくれるため、余計に混乱してしまうんですよね。
機能的な違いを簡単にいうと、Functionは戻り値を返すことができて、Subは戻り値を返すことができません。
いきなり「戻り値」といわれてもよく分かりませんが、戻り値はプログラムを実行した結果を報告する機能なんですね。
FunctionとSubの違い
ココがポイント
- Function :戻り値を返す
- Sub:戻り値がない
基本的にはVBAで何か処理をしたい場合は、Subを使うことが多いと思います。
無理してFunctionを使わずに、Subを使ってVBAに慣れていきましょう。
決まった処理をSubで作っておいて、好きなタイミングでSubプロシージャを実行してみて下さい。
何度も同じことをする必要がなくなるため、プログラムの動きを体験して便利さを実感できますよ。
戻り値って何?実行したあとに結果を返すこと
FunctionとSubの違いは戻り値を返すか、返さないかの違いになるとお伝えしました。
エクセルのマクロで考えた場合、複数の処理に対して結果を返す必要な状況がなかなか浮かばないと思います。
戻り値の考え方があると、FunctionとSubの実行する方法が見えてきますよ。
ポイント
- Subは戻り値がないため、単独で実行
- Functionは戻り値があるため、SubかFunctionから呼ばれて実行
Functionはプログラムからプログラムに処理をお願いするときに使うことが多いです。
簡単な使い方としては、お願いした処理が成功したのか、失敗してしまったのかを戻り値を使って教えてもらったりしますね。
Subはプロシージャの中の処理で全てが完了するため、結果を必要としないときに使われます。
プログラムを作ったことがない人からすると分かり難い考え方なので、しっかりと理解しておくといいでしょう。
Functionで作ってしまったものをSubにできるの?戻り値の考え方が分かれば変更可能
プログラムを作ってる人からするとよくあることですが、仕様がころころと変更されることがよくあります。
Functionで作ったプロシージャをSubにして欲しいなんてこともあった場合、簡単に変更できると思いますか?
逆にSubプロシージャをFunctionにしたいなんてこともあるでしょう。
FunctionとSubの違いは戻り値だけなので、そこを修正するだけで簡単に変更ができます。
少しずるいかも知れませんが、Functionプロシージャでは値を戻さなくてもエラーになりません。
後からSubやFunctionの変更がある可能性があるなら、はじめからFunctionプロシージャとしておいた方が、手間が減ることもありますよ。
FunctionとSubでどちらを使えばいいの?用途の違いで使い分けよう
FunctionやSubプロシージャを実行するときに、「引数(ひきすう)」と呼ばれるものを指定することができます。
引数はプロシージャを実行するときに使う値のことで、入力した値を使った処理が実行されます。
Excel(エクセル)のマクロやVBAの関数でFunctionやSubで引数を使う場合、複数指定することも可能ですよ。
Subはどんなものなの?決まった処理がひとまとまりにしたもの
Subプロシージャは「Sub」から「End Sub」の間に、処理を記述していきます。
この間に記述した処理を順番に実行していくため、やりたいことをまとめて記述することで一気に実行してくれます。
Subプロシージャには名前も指定できますが、ルールがあるので注意が必要です。
アルファベット、ひらがな、カタカナ、漢字は使えますが、数字を使う場合は名前の先頭に使えませんし、記号もほとんど使えないと覚えておくと良いでしょう。
「_(アンアダーバー)」は使えます。
Functionはどんなものなの?引数によって戻り値が変わるため引数を使うことが多い
FunctionプロシージャもSubとほとんど同じように使いますが、引数を与えてその処理結果を受け取ることを目的として使います。
引数はなくてもいいですし、複数指定することもできるので、作りたい処理によって変えてみましょう。
あとはSubプロシージャと同じく、名前のルールを守って作る必要があります。
初めはSubプロシージャだけでもエクセルのマクロは作ることはできるため、Functionプロシージャの必要性を感じないかもしれません。
戻り値を返すことができるFunctionを使うと、プログラムを作る上で一気に幅が広がり、分かりやすいコードが書けるのでFunctionプロシージャにもチャレンジしてみて下さいね。
Subでは値を返せないの?Subでも値を返す方法を紹介
Subプロシージャには戻り値はありませんが、値を返す方法があります。
プログラムには抜け道もあるため、戻り値のないSubでも処理の結果を返す二つの方法をご紹介しますね。
どこからでも参照可能な変数がある?グローバル変数を使おう
プログラムには変数と呼ばれる、値を入れられる箱があります。
この変数は宣言したSubやFunctionの中でしか使うことができないため、SubやFunctionが実行されるたびに初期化されてしまうんです。
この変数をローカル変数といって、使える範囲が限定されている変数ですね。
変数にはもう一つあって、グローバル変数と呼ばれる、どこでも使える変数があります。
これを使えばSubの中で変更した値が、呼び出し側でも見ることができます。
このグローバル変数を使うことで、どこからでもアクセス可能にはなりますが変数の値がどこで変わるか把握が困難なため、基本的にはあまり使いません。
参照渡しってなに?Subプロシージャに引数を渡す
Subプロシージャは処理結果を必要としない場合に使うため、引数を使うことは少ないかも知れませんが引数の指定ができます。
引数の定義方法を変えてあげると、呼び出し側が指定した引数の値を変更することができますよ。
通常はByValで引数を定義しているところを、ByRefに変更します。
ByRefで定義した値をSubプロシージャで変更した場合、呼び出し側の変数も変わってくれる方法ですね。
サンプルがありますので参考にしてみて下さい。
「moji」変数に「おはよう」を入れておいて、SubプロシージャにByValとByRefでそれぞれ値を渡します。
Subプロシージャの中で「おはよう」から「こんにちは」に変更した場合どうなるか?
実際にExcel(エクセル)でVBAやマクロから関数を使って、FunctionやSubを呼び出した場合、どのようになるのか見てみましょう。
ポイント
- ByValの引数の値は「おはよう」から変更がありません
- ByRefの引数の値は「おはよう」から「こんにちは」に変更されます
ByValの場合
①「moji」に”おはよう”を入れておく
②testByVal(moji)で呼び出す
Sub Main()
Dim moji As String
moji = "おはよう"
call testByVal(moji)
MsgBox moji
End Sub
③mojiを”こんにちは"に変える
Sub testByVal(ByVal moji as String)
moji = "こんにちは"
End Sub
④メッセージで「moji」の中身を確認
「おはよう」と表示される
ByRefの場合
①「moji」に”おはよう”を入れておく
②testByVal(moji)で呼び出す
Sub Main()
Dim moji As String
moji = "おはよう"
call testByRef(moji)
MsgBox moji
End Sub
③mojiを”こんにちは"に変える
Sub testByRef(ByRef moji as String)
moji = "こんにちは"
End Sub
④メッセージで「moji」の中身を確認
「こんにちは」と表示される
Functionのイメージはこれ!エクセルの関数と同じで処理の結果が返ってくる
Functionプロシージャというと身構えてしまうかも知れませんが、考え方としてはSUMやIFなどの関数と同じです。
例えばSUMなら範囲を指定してあげれば合計値を表示してくれますが、Functionも何かを指定したら処理結果を返してくれます。
当然、FunctionでSUMと全く同じこともできますよ。
Functionはあなたが作った処理結果を返してくれる、あなた専用関数になる訳です。
エクセルで用意されている関数と比べると、あなたが関数を作った場合には注意が必要です。
それはバグが発生する可能性があります。
バグとはプログラムに潜んでいる誤った処理のことで、プログラムの規模が大きく複雑になるほどバグも増えてしまうものです。
しっかりと色んなパターンでテストをしてから、Functionを使うようにしましょうね。
バグを恐れていても始まらないので、まずは簡単なプロシージャを作ってみましょう。
バグを発見した時の対処方法はこちらを参照にしてくださいね。
FunctionとSubの違いのまとめ
FunctionとSubの違いが分かって頂けたでしょうか?
Functionプロシージャは戻り値があり、Subプロシージャは戻り値はないため、処理結果を受け取れるから受け取れないかの違いでした。
実際にVBAでプログラムを組んでみないと、FunctionとSubが分かれている理由が分からないと思います。
慣れてくれば理解できますので、初めは簡単なマクロを作ってみるところから始めてみませんか?