エラー内容
エラー28(スタック領域が不足しています)は関数の呼び出し順序を覚えられない状態に陥ったことを表しています。
関数の呼び出し順序を記憶しているのがスタック領域です。
ほとんどの場合はプログラムの修正が必要です。
エラー原因
Microsoftのヘルプでは5つ程度のエラー原因を挙げていますが、このエラーが発生する一番の原因は「再帰呼び出しが多すぎる」という場合です。
再帰以外の原因でのエラーを発生させてみようと思い、わざとエラーになるようなコードを書いてみましたが再現しませんでした。
以下はMicrosoftのヘルプです。
https://msdn.microsoft.com/ja-jp/vba/language-reference-vba/articles/out-of-stack-space-error-28?f=255&MSPPError=-2147217396
再帰呼び出しとは、関数が自分自身を呼び出している状態を言います。単純な再帰呼び出しはこのような状態になります。このコードはエラー28が発生します。
1 2 3 4 |
Sub Recursion(i) i = i + 1 Call Recursion(i) End Sub |
何階層も関数が自分自身を呼び出したとしても、最終的には一番最初に呼び出した処理に戻らなければなりません。
そのためどの関数がどういう順番で呼び出されたのかをスタック領域で管理するのですが、管理しきれなくなったのがエラーの原因です。
スタック領域は言語によってサイズが異なりますが、VBAの場合は上記のような単純な関数であれば関数の呼び出し階層が5000階層程度になるとエラーになります。
1 2 3 4 5 6 7 8 9 |
呼び出し元関数 1階層 Recursion 2階層 Recursion 3階層 Recursion 4階層 Recursion 5階層 Recursion 6階層 ・・・・ Recursion 4999階層 Recursion 5000階層 ←このあたりでエラー発生 |
エラー対応方法
エラー28を発生させないようにするには、再帰呼び出しをやめるのが一番です。
再帰をしない構成にプログラムを変える必要がありますが、基本的にはループ処理への書き換えになります。
元の再帰呼び出しの処理をループ内で処理するように変更します。ループ内で呼び出すのであれば階層呼び出しにならない構成にもできますので、本処理自体は関数化しておき、それをループで呼び出すようにするなどの対応を行います。