いや、ここはSubじゃない・・「Functionだ!」と感じるとき(をゆるく説明します)

慣れるまでは把握しづらいSubとFunctionの違い

Excelに慣れ、関数にも慣れ、その他の機能にも慣れてくると、効率化の代表的な手法である「マクロ」にも目が届き始めるというような流れは割にあると思います。

マクロの記録から始まり、それをゴニョゴニョといじり、さらには一からプロシージャを作り上げていく、、
多くの人がこのような流れで進んでいくのではないかと思います。
そしてその過程で、「Functionプロシージャ」なるものに出会うわけですね。

このFunctionですが、Subと同じようなことができます。したがって、慣れてないと、そもそも「どのように使うのか分かりにくい」ことが特徴でもあると思います。

そこで、今回はFunctionについて、「こんなときに使いたい」ということを、技術的な部分も出てきますが、できるだけ難しくならないよう「ゆるく」説明したいと思います。

FunctionとSubのどちらを使うか悩む・・
なお、Functionは当サイトでもページ(自作関数を使うと「ハッピーな業務」になるのか)がありますが、「ユーザー定義関数」を作ることができます。これもSubとの大きな違いですが、このユーザー定義関数も結局のところ「値を返す」ということに行き着きます。

おそらく多くの方は「そんなこたぁ分かってる」だろうということを前提にプログラム的な視点から説明したいと思います。

「できることはほぼ同じ」・・だからこれで比較しても分かりづらい

Functionプロシージャの最大の特徴は、「値を返す」ことだと思います。
これがなければ、全部Subで十分という話になるくらいな特徴を持っていると思います。

そもそもSubとFunctionでは、ほとんど同じ実装ができてしまいます。

「差がない」

これがあるからこそ、しっくりこないことが多いのではないかと推測します。

だからこそ、「値を返す」という特徴を上げたのですが、残念ながらとでもいいますか、実はSubでも値を返すことができます(厳密にはこの「返す」という表現は違うと思いますが・・)。
となると、余計に差が見えなくなってしまいますよね。

SubとFunctionで、物理的というか論理的というか、そういった面の違いだけで理解を得るのは難しいのではないかと思いました。
(これだけでは表面的な内容に傾いてしまいそうです)

そこで、SubとFunctionの違いを知るためには、そもそも別の目線で見ていかないと分からない、あるいは分かりづらいということを意識して説明します。

「Functionが必要」と感じるためには、ある程度の「スキル」が必要

このページを読む方によっては、いきなりハードルを上げられたかのような項目の見出しに見えてしまうかもしれません。
しかし「SubとFunction」の違いを知るためには、ある程度の(前提)スキルが必要になると思うのですね。

独断と偏見ですが、以下のようにスキルを分類し、みなさんがどの位置にいるのかにより、今回説明の理解の度合いが変わってくると思います。

Functionを理解できるだろうスキル分類
プログラマーという人たちは、マクロの記録から始まり、その記録に少しずつ手直しを加え、最後は参考程度にし、自身でプロシージャを作っていく・・そんな流れになると思います。

上記のスキルの順序や内容は独断と偏見です。他の方と言っていることが違う場合、この点にご注意くださいませ。

ここでSubとFunctionを理解するために必要なスキルは、上から1番目、2番目の部分ですね。
「長~いマクロ(VBAコード)」に心地悪さ?を感じ、複数に分割する、分割したいと思い始めるレベルです。
そしておそらくはこの辺のスキルの方々がSubとFunctionの違いの説明を理解できるのではないかと思います。

もちろんマクロを覚え始めた方でも理解できるかもしれません。ただ、多分ですが、マクロを覚え始めた方にとっては、「言ってる意味は分かる、でも、だから何?」という感じになるのではないかと思います。

当ページを読んで、しっくりこない方は、私の説明がいただけない(笑)か、あるいはもしかしたらこの辺が影響しているのではないかと思います。

「コードの分割」でプログラムの効率性を上げる・・Functionを使う必要性

先ほどFunctionは、「値を返すことが特徴である」と言いました。
この値を返す特徴を利用することで、「プログラムの外出し」とでもいえるやり方が可能になります。

1つのプロシージャに全部の機能を詰め込む
例えば、上の処理のように1つのマクロ(プロシージャに)に、大きく4つの処理があるとします。

それを下記のような形にしておきます。ここで言う「分割(外出し)」とはこんな意味ですね。

1つのプロシージャを複数のプロシージャに分割する
プロシージャを分割すると、処理は上から「一筆書き」のように流れていきます。本流から支流にいき、また本流に戻ってくるイメージですね。

分割自体はFunctionでもSubでも可能ですが、この例では、Subのみで分割しているイメージになっています。Functionでも同様ですね。

ここでは説明の便宜上、Functionの用途を「分割のため」に限定している書き方になっていますが、これはその限りではないのでご注意です。

ここで押さえておくべき点としては、分割の仕組みと意図ですね。慣れてくると難しい話ではないと思いますが、特に「なぜ分割する?」の意図が見えてこないと、Functionで分割する意味も見えてこないと思います。
ただし、この辺りはプログラマーや開発チームの考えに依存するところもあると思います。つまり「分割なんて要らないっしょ」ということもあるかもしれませんので、説明がやや難しいのですが(笑)。

とは言っても、プロシージャを分割することは、プログラム全体の見通しをよくできます。そしてFunctionを使って分割することで、「Subにはない側面を引き出す」ことができます。

分割の例:Functionで値の検証をする

このような分割をFuctionで行った状態であるならば、Functionでよく見かけるのは「値の確認」プロシージャです。

これまで説明しているように「Functionは値を返します」。
あるデータが正しいのか、間違っているのか、これを外に出したFunction内でチェックします。

  • そして、そのデータがOKならば「TRUEを返す」
  • そして、そのデータがNGならば「FALSEを返す」

として、「値を返す」ようにします。

こうすることで外に出せるわけですね。
Functionで値を判定する

そして、「メイン」では、その「Functionの結果(Functionが返した値)」を受け取り、次の処理に繋げるイメージです。

実際には、単なる分割という意味だけでなく、Functionに似たような処理を受け持たせるように汎用的に作っておくことで、メインだけでなく「別の処理からも呼び出せる」などすると、効果はより大きくなります。

なぜ、こうするのかと聞かれれば、それは「メインのコードの可読性がよくなり、全体の流れを追いやすくなるから」になると思います。
「支流の結果を受けて(Functionから何らかの値を受け取り)、本流で作業の流れをコントールできるから」とも言えますね。

なぜ、それが「Subでなく、Functionなのだ?」と聞かれれば、それは「値のチェックを行い、それがOKなのかNGなのか、その値を返すから」となると思います。
Functionの方が都合が良いわけですね。

まとめ

いかがでしょうか?おそらくマクロに慣れてない方が見ると、「うーん、メリット感じない」となるかもしれません(笑)。
しかし、このようにすることでプログラムの可読性を上げたり、機能をまとめて外に出すことで改修メンテナンスもしやすくなります。

となると、Functionが必要と感じるには、やはりある程度のスキルが必要となると思います。
難しいように感じる方もプログラムに慣れれば、必ず理解できると思います。

頑張ってくださいませ。

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