プロシージャを理解する

プロシージャを理解する

前回は簡単なプログラムを作成して、そのプログラムを実行するところまでを解説させて頂きました。

その中で耳慣れない「プロシージャ」という言葉があったかと思いますが、憶えていますでしょうか。

解説の中でも補足はしましたが、プロシージャについてまだまだ説明が足りていませんので今回のテーマとして「プロシージャ」を取り上げてみたいと思います。

VBAのプログラミングの第1歩としてプロシージャについての理解を深めましょう。


プロシージャとは

プロシージャとはプログラムとして実行可能な処理を定義したものです。

VBAで何かの処理をプログラミングすることになった場合、それはプロシージャを作成作業することと言っても過言ではありません。

プロシージャに以下の2つが存在します。

  • Subプロシージャ
  • Functionプロシージャ

どちらも処理を実行することには変わりありませんが、実行後に違いがあります。

  • Subプロシージャは何もせずそのまま終了する。
  • Functionプロシージャは終了時に値を返すことができる。

「えっ?値を返す?」

その疑問は正しいです。

学びの場ではどんどん疑問を解消していきましょう。

「値を返す」という言葉から何となく連想はできるかもしれませんが、しっくりくる解説をしたいと思います。

例えば、数字の計算を処理するプログラムがあったとしましょう。

結果をメッセージボックスに表示させたり、ファイルに書き込んだりするだけならばSubプロシージャでも定義することが出来ます。

しかし結果を元に次の処理を実行させたい場合、メッセージボックスでの結果は消えてしまうし、ファイルに書き込んだ場合は結果を知るためにわざわざファイルを開かなければなりません。

話を聞くだけでも正直、面倒くさそうですよね。

Functionプロシージャは処理を実行した結果を返すことができるのです。

「だからさっきから値を返すって、、、どこに返すのよ?」

そうですね。返すと言ってもどこに返すのかって話もありますね。

少し補足しますと、プロシージャは処理の中で別のプロシージャを呼び出して実行することができるのです。

呼び出せるプロシージャはSubプロシージャでもFunctionプロシージャでもどちらも呼び出しが可能です。

つまりメインプロシージャで計算に使用する値を定義して、その計算の部分だけの別のプロシージャを呼び出して処理をお願いしたいようなケースに該当します。

メインプロシージャとしては計算結果を知った上で続きの処理を実行していきたいので、別のプロシージャの処理の結果がどうなったか知りたいわけです。

そこでFunctionプロシージャの出番です。

Subプロシージャでは値を返すことが出来ませんが、Functionプロシージャでは結果を返すことができるんですね。

これからVBAの学習をしていく上で多くのプロシージャに出会うことになるでしょう。

そこでは処理の実行手順や実現するための手法などプログラミングのテクニカルな部分を読み解いていくことができます。

そのとき処理になぜSubプロシージャで定義されているのか、なぜFunctionプロシージャで定義されているのか、など着目してみてください。

その観点はVBAプログラミング上達への近道になることでしょう。

Subプロシージャの記述方法

subプロシージャの記述方法について解説していきます。

記述方法にはいくつかルールがあります。

  • 「Sub [プロシージャ名]()」で始まって「End Sub」で終わる
  • Subとプロシージャ名の間は半角スペース
  • プロシージャ名は基本的に自由
  • 複数のプロシージャ名を定義する場合、同じプロシージャ名はNG
  • プロシージャ名は半角全角のアルファベット、ひらがな、漢字、数字、記号のアンダースコアが使用可能
  • プロシージャ名の先頭は半角全角のアルファベット、ひらがな、漢字のみ使用可能
  • プロシージャ名の後に半角括弧「()」を付ける
  • 具体的な処理内容を記述する
  • コメントには文頭に「’」半角シングルクォーテーションを付ける
Sub Sample()

	'具体的な処理内容を記述していく

End Sub

上の例はプロシージャ名をSampleと名付けたSubプロシージャで、コメントだけでVBAでの具体的な処理の記述がないので実行することは出来ても、即時に処理が終了してしまいます。

プロシージャ名の隣に半角括弧「()」がありますが、この括弧内にプロシージャで使用する引数を定義することができます。

プロシージャで使用する引数についての詳細は次回以降で取り上げていきたいと思います。

以下のソースコードはいかがでしょう。

Sub Sample_001()
	MsgBox 1
	Call Sample_002
	Call Sample_003
	Call Sample_004
	MsgBox "終わり"
End Sub

Sub Sample_002()
	MsgBox 2
End Sub

Sub Sample_003()
	MsgBox 3
End Sub

Sub Sample_004()
	MsgBox 4
End Sub

ここには複数のSubプロシージャ(Sample_001~Sample_004)が定義されています。

Sample_002~Sample_004までは単純にメッセージボックスに数字を出力するだけの処理ですが、Sample_001だけ少し異なります。

Sample_001では処理の途中で別のプロシージャを呼び出しています。

プロシージャの呼び出し方は「 Call [プロシージャ名] 」となります。

ちなみに[プロシージャ名]だけでも呼び出し実行が可能ですが、明示的に「Call」を付けている方が別プロシージャの呼び出しについての読み解けやすさがあります。

プロシージャの実行は上から順に実行されていきますので、Sample_001を実行すると以下のような順でメッセージボックスが出力されます。

  1. メッセージボックスに「1」が出力される。
  2. メッセージボックスに「2」が出力される。
  3. メッセージボックスに「3」が出力される。
  4. メッセージボックスに「4」が出力される。
  5. メッセージボックスに「終わり」が出力される。

Functionプロシージャの記述方法

Functionプロシージャの記述方法について解説していきます。

Functionプロシージャにも記述方法にルールがありますが、Subプロシージャとほぼ同じ内容になっております。

  • 「Function[プロシージャ名]()」で始まって「End Function」で終わる
  • Functionとプロシージャ名の間は半角スペース
  • プロシージャ名は基本的に自由
  • 複数のプロシージャ名を定義する場合、同じプロシージャ名はNG
  • プロシージャ名は半角全角のアルファベット、ひらがな、漢字、数字、記号のアンダースコアが使用可能
  • プロシージャ名の先頭は半角全角のアルファベット、ひらがな、漢字のみ使用可能
  • プロシージャ名の後に半角括弧「()」を付ける
  • 具体的な処理内容を記述する
  • コメントには文頭に「’」半角シングルクォーテーションを付ける
Function Sample()

	'具体的な処理内容を記述していく

End Function

上の例はプロシージャ名をSampleと名付けたFunctionプロシージャで、Subプロシージャの例と同様にコメントだけでVBAでの具体的な処理の記述がないので実行することは出来ても、即時に処理が終了してしまいます。

以下は複数のFunctionプロシージャの記述例です。

Function Sample_001()
	MsgBox 1
	MsgBox Sample_002
	MsgBox Sample_003
	MsgBox Sample_004
	MsgBox "終わり"
End Function

Function Sample_002()
	Sample_002 = 2
End Function

Function Sample_003()
	Sample_003 = 3
End Function

Function Sample_004()
	Sample_004 = 4
End Function

この例は少し意地悪な例なんですが、解説していきたいと思います。

基本的にSubプロシージャのSample_001の処理と同じ実行結果が再現される内容になっていますが、雰囲気がSubプロシージャの感じと違いますよね。

Sample_002~Sample_004まではプロシージャ名にイコールで数字を設定しているだけですし、Sample_001では別プロシージャが「Call」で呼び出されていないですし。。。

すでにFunctionプロシージャは値を返すことができることは説明済みですが、これがその例になります。

プロシージャ名にイコールで値を設定すると、そのプロシージャが呼び出された時にその値がFunctionプロシージャから返り値として出力されてきます。

Sample_001では呼び出したFunctionプロシージャからの返り値をそのままダイレクトにメッセージボックスに出力させています。

Sample_002~Sample_004のプロシージャを単体で実行してもメッセージボックスが出力されないのでまったく同じと言えないですが、Sample_001に関しての処理は同等の結果になります。

ちなみに以下のように全く同じに似せてソースを作り変えることも出来ます。

Function Sample_001()
	MsgBox 1
	Call Sample_002
	Call Sample_003
	Call Sample_004
	MsgBox "終わり"
End Function

Function Sample_002()
	MsgBox 2
End Function

Function Sample_003()
	MsgBox 3
End Function

Function Sample_004()
	MsgBox 4
End Function

これだとSubプロシージャと全く同じ内容になり、違いは定義したプロシージャの種類だけになります。

そういった場合だと返り値を必要としない処理のため、Subプロシージャの定義を適用するのが望ましいと言えるでしょう。

まとめ

プロシージャについて解説させて頂きましたが、いかがでしたでしょうか。

プロシージャの引数や返り値のデータ型についてはここでは取り上げていませんが、次回以降で変数やデータ型を扱うテーマで取り上げていく予定です。

Functionプロシージャのメリットや恩恵は、入門で使用するサンプルではなかなか見い出しにくいかもしれませんが、使いこなせれば強力な味方になります。

応用編や実践編など難易度が上がるにつれてFunctionプロシージャが増えてくる傾向にあると思います。

使い方はスキルに応じた使い方でいいと思いますが、「Subプロシージャの方がシンプルだから~」というような気持ちからプロシージャの使い方が偏っていかないように、しっかり「使い分け」の観点での経験も積んでいきましょう。