Sub Sample1()
Call Sample2
End Sub
Sub Sample2()
Call Sample1
End Sub
上のコードは、非常に分かりやすい例です。
あるプロシージャから別のプロシージャを呼び出す(コールする)と、VBAはスタック領域という記憶場所に、"どのプロシージャがどのプロシージャを呼び出したか"を記録しておきます。そうしないと、呼び出されたプロシージャが終了したとき、最初のプロシージャに戻れませんからね。
しかし、その記憶場所であるスタック領域には限度があります。「AがBを呼んで、BがCを呼んで、CがDを呼んで、DがEを・・・あぁ、もう覚えきれません..._| ̄|○」という状態が、このエラーです。上のコードみたく、お互いを無限に呼び合うようなミスをすると、VBAのスタック領域はすぐ一杯になります。
このように、このエラーは他のプロシージャを呼び出すときにも起こりがちですが、それよりも自分自身を呼び出す再帰プロシージャで注意が必要です。次のコードは、サブフォルダの一覧をワークシートに出力するマクロです。Sample4は再帰プロシージャになっています。
Sub Sample3() Call Sample4("C:\Work") End Sub Sub Sample4(Target As String) Dim folder As Object Static cnt As Long With CreateObject("Scripting.FileSystemObject") For Each folder In .GetFolder(Target).SubFolders cnt = cnt + 1 Cells(cnt, 1) = folder.Name If folder.SubFolders.Count > 1 Then Call Sample4(folder.Path) ''自分自身を呼び出している End If Next folder End With End Sub
こうした再帰プロシージャでは、スタック領域に記憶される"呼び出し履歴"が、どうしても増大します。上のコードでは、あまりに深いフォルダ階層を取得しようとすると「スタック領域が不足しています」エラーが発生するかもしれません。