スタック領域が不足しています。(エラー番号:28)


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

こうした再帰プロシージャでは、スタック領域に記憶される"呼び出し履歴"が、どうしても増大します。上のコードでは、あまりに深いフォルダ階層を取得しようとすると「スタック領域が不足しています」エラーが発生するかもしれません。