ユーザー定義関数(Sub)の使い方

かばくん

複雑なプログラムを書いていたら、縦にすごーく長くなってきました
読みづらいし、デバッグも大変です。何か対策はありますか??

へびせんせい

複雑なプログラムになると、ある程度は仕方ないですが、関数を使うと解消されるかもしれません
長いプログラムは処理や動作ごとに関数にすることで、たくさんのメリットがあります。

関数を使うメリット
  1. コードがわかりやすくなる
  2. 重複を減らし、繰り返し使うことができる
  3. 複数人での開発を行いやすくする

プログラミングにおける関数とは?

関数を使う場合と使わない場合のイメージ

関数を使うとプログラムを細分化できる

今まで、一つのSubプロシージャーのみに、コードを書いていました。
そうすると、複雑なプログラムになると、すごく長いコードになってしまいます。
そこで、処理ごとに関数にして、その関数を呼び出すことで、長いコードを処理ごとに分割することができます。

VBAでの関数は、

  • Subプロシージャー ・・・ 値を返さない
  • Functionプロシージャー ・・・ 値を返す

の2つがあります。
このセクションでは、値を返さないSubプロシージャーについてみていきます。

値を返さない? 値を返す?

その関数が値を返すのか、返さないのかは関数をどう動かすかで決まります。
例えば、ある範囲のセルのRangeを関数に入力したとします。その結果、

  • 値を返さない関数・・・Rangeのセルの背景色を赤にする
  • 値を返す関数・・・Rangeのセルの中の最大値を求めて、その値を返す

値を返さないものは、関数の中で処理が完結するもの。
値を返すものは、その結果を使ってさらに次の処理で使うもの。とも言い換えることができます。
また、この値のことを、返り値(またな戻り値)といいます。

関数とは自動販売機のイメージ

プログラミングにおける関数のイメージ

プログラミングでいう関数を自動販売機で例えてみます。
関数とは、なにかの入力に対して、出力を行う装置のようなもの。
自動販売機は、お金を入力すると、そのお金に見合ったジュースを出力します。
このとき、開発者ではない多くの人は、自動販売機がどういう仕組で動作しているかは知らないでしょう。
関数も同じで、自分で作るときは中身を完全に理解する必要がありますが、そうでないときは、使い方だけ知っておけばよいのです。

値を返さないSubプロシージャー

Subプロシージャーを呼び出すCall

Subプロシージャー(関数)を定義することは今までと同様です。
その関数を他のSubプロシージャーから呼び出すことで関数として使うことができます。
呼び出し方は、

Call プロシージャー名
Sub main()
  Call InputHello
End Sub

Sub InputHello()
  Range("A1").Value = "hello"
End Sub

mainというマクロを実行すると、InputHelloという関数が呼び出されて、A1セルにhelloという文字列が入力されます。
もちろん呼び出し元である「main」というSubプロシージャー名はどんな名前でもかまいません。

関数に引数を渡す方法

関数には引数を設定することが可能です。
引数とは、関数の中に数字や文字列を付与することで、任意の値を使って関数内で処理を行わせるもの。
引数によって、関数の中のデータ(値)を返ることができます。

関数に引数を設定するには

Sub プロシージャー名(引数名 As 型名)

関数を定義するときに、()の中に引数名とその引数の型を指定すると、その関数は引数をもつことができます。
関数の中で、引数を使って演算することができます。

関数を呼び出すには

Call プロシージャー名(引数)

Callを使うのは同じですが、引数がある場合は、プロシージャー名のあとに引数を指定する必要があります。
引数は、そのまま数値や文字列を入力してもよいし、同じ型の変数を送ってもよいです。

どっちでもOK!
Call プロシージャー名(3)
Call プロシージャー名(num)

また、引数は「,」でつなげることで、複数の引数を設定することができます。

Call プロシージャー名(引数,引数,引数)

引数に配列を指定するには

引数を配列にすることもできます。
引数のあとに()をつけるだけ。

Sub プロシージャー名(引数名() As 型名)
*引数を自動販売機に例えるなら
自動販売機にはお金を入力しますが、その金額がいくらなのかは引数で表すことができます。
そして、自動販売機の中で金額に応じた量のジュースが出力されるように設計されているでしょう。

「自動販売機という関数に200円の引数を送って呼び出す」には、
    Call 自動販売機(200)

Subプロシージャーのコード例

Sub main()
  Dim a As Long
  Dim b As Long
  
  a = 100
  b = 150
  
  Call GetLargerNumber(a, b)
End Sub

Sub GetLargerNumber(num1 As Long, num2 As Long)
  If num1 > num2 Then
    MsgBox (num1 & "の方が大きい数字です")
  Else
    MsgBox (num2 & "の方が大きい数字です")
  End If
End Sub

この例では、main関数で、2つの整数を定義しています。
そして、その2つの整数のどちらが大きい数字かを判別するための関数をGetLargerNumberという関数です。
この関数には、2つの整数を送る必要があるため、定義のときに、引数を設定しています。
試しに、aとbの値だけを変えて実行してみてください。関数の方は何も変えなくても、正しい結果が出力されるはずです。


Subプロシージャーの練習問題

へびせんせい

main関数で4つの整数を定義し適当な数値を代入し、それをGetMaxValue関数に渡せ。
GetMaxValue関数は4つのLong型の引数を設定し、その4つの整数の最大の値をMsgBoxで出力するものとする。
*上のGetLargerNumberを修正しながら作成すると容易

解答はコチラ

Excelを開いて、コードを確認してください

Download