オーロラさんの勉強帳

IT企業勤務。データベース、Excel、Excel VBA、ネットワーク、LinuxなどIT関連のことを主に書いていきます。少しでもお役に立てたら幸いです。

【Excel VBA】再帰呼出しをVBAで試してみる ~再帰呼出しの動きをわかりやすく解説~

プログラムが自分自身を呼び出す処理のことを「再帰呼出し」といいます。
実際にVBAのコードで「再帰呼出し」の動きをわかりやすく解説します。

階乗を求める再帰呼出しのVBAコード

4の階乗を求めるVBAのコードです。
FunctionプロシージャのsampleRecursiveで「再帰呼出し」にて、4の階乗を求めています。

Sub sampleCall()
  MsgBox sampleRecursive(4)
End Sub

Function sampleRecursive(ByVal n As Long) As Long
    If n <= 1 Then
        sampleRecursive = 1
    Else
        sampleRecursive = n * sampleRecursive(n - 1)
    End If
End Function

※Sub sampleCallのMsgBox sampleRecursive(4)の()内の数字「4」を任意の数字に変えると、その数字の階乗を求めることができます。


上記コードを動かしてみると、4の階乗(4×3×2×1)の24がメッセージボックスで表示されます。


再帰呼出しの動作を画像で分かりやすく解説

以下の画像は再帰呼出しの前半部分の解説画像です。
Subプロシージャ「sampleCall」からFunctionプロシージャ「sampleRecursive」を呼び出します。その際に引数として「4」を渡します。
Functionプロシージャ「sampleRecursive」で自分自身を呼出す際は、3、2、1と引数を渡していきます。

再帰呼出し

以下の画像は、再帰呼出しの後半部分の解説画像です。
『sampleRecursive = n * sampleRecursive(n - 1)』『sampleRecursive(n - 1)』に返り値(1、2、6)を返して、階乗を計算していきます。
※2*1⇒3*2⇒4×6で24求めています。
そして、再帰呼出しで求めた24をSubプロシージャ「sampleCall」に返して、メッセージボックスに表示しています。

再帰呼出し


4の階乗を再帰呼出しで求める動作の流れは以下の通りです。

再帰呼出し 4の階乗

再帰呼出しの動作を考える(文字ベース)

大きな動きは以下の図の通りです。上記では画像ベースで説明したので、テキストベースで1つずつの処理を解説します。

再帰呼出し

<Subプロシージャ:sampleCall>
1~2:Subプロシージャ「sampleCall」からFunctionプロシージャ「sampleRecursive」を呼び出します。その際に引数として4を渡します。

<FunctionプロシージャsampleRecursive>
4:Functionプロシージャ「sampleRecursive」でnには4が渡されています。
5:IF文でnが1以下かどうかで処理を分岐しています。(n=4なので8行目に移動)
8:sampleRecursive = n * sampleRecursive(n - 1)では、sampleRecursive =4*sampleRecursive(3)となります。sampleRecursive(3)で自分自身のFunctionプロシージャ「sampleRecursive」を呼び出します。
その際、引数に3を渡します。

引数に3を渡したFunctionプロシージャ「sampleRecursive」でも、8行目でさらに自分自身のFunctionプロシージャ「sampleRecursive」を呼び出します。
その際、引数に2を渡します。
引数に2を渡したFunctionプロシージャ「sampleRecursive」でも、8行目でさらに自分自身のFunctionプロシージャ「sampleRecursive」を呼び出します。
その際、引数に1を渡します。

引数に1を渡したFunctionプロシージャ「sampleRecursive」では、6行目でsampleRecursive=1で返し値として1を格納。
9~10行目のEnd If、End Functionで呼出し元に返り値1を返します。

呼出し元は「sampleRecursive = 2 * sampleRecursive(2 -1)」の『sampleRecursive(2 -1)』です。sampleRecursive(2 -1)に返り値1が入るので、「sampleRecursive = 2 * 1」(返り値が2)となります。
9~10行目のEnd If、End Functionで呼出し元に返り値に2を返します。

呼出し元は「sampleRecursive = 3 * sampleRecursive(3 -1)」の『sampleRecursive(3 -1)』です。
sampleRecursive(3 -1)に返り値2が入るので、「sampleRecursive = 3 * 2」(返り値が6)となります。
9~10行目のEnd If、End Functionで呼出し元に返り値に6を返します。

呼出し元は「sampleRecursive = 4 * sampleRecursive(4 -1)」の『sampleRecursive(4 -1)』です。
sampleRecursive(4 -1)に返り値6が入るので、「sampleRecursive = 4 * 6」(返り値が24)となります。
9~10行目のEnd If、End Functionで呼出し元に返り値に24を返します。

呼出し元Subプロシージャ「sampleCall」のMsgBox sampleRecursive(4)の『sampleRecursive(4)』です。
メッセージボックスに24を表示して、処理を終わります。


以上、再帰呼出しの解説です。
お読みいただきありがとうございました。