エラー内容
VBAコンパイル時に、「Sub または Function が定義されていません。」と表示される。
原因と解決方法
おもに次の3つの原因と解決方法が考えられます。
原因1. プロシージャが存在しない
解説
エラー内容そのままで、呼び出し先のプロシージャ(sub,function)が存在しない時に起こります。
ウェブの参考プログラムや、他のファイルからコピーした時などに、呼び出し先のコピーが漏れている時によく起こるエラーです。
1 2 3 4 5 6 7 8 |
'修正前 Sub ErrSample02_01() Call JidouKeisan '← プロシージャJidouKeisanが定義されていない End Sub |
解決方法
呼び出し先のプロシージャ(sub,function)定義も、プログラムに記述します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
'修正後 Sub ErrSample02_01() Call JidouKeisan End Sub Sub JidouKeisan() '← プロシージャJidouKeisanの定義を追加 'ここは実際の処理をプログラム End Sub |
原因2. プロシージャがPrivateで他モジュールで定義されている
解説
他の標準モジュールにプロシージャ(sub,function)はちゃんと定義しているけど、Privateで宣言されている時に起こります。
下のプログラムのように、Module1にプロシージャの定義がPrivateでされ、Module2から呼び出した場合です。
Module1
1 2 3 4 5 6 7 |
Private Sub JidouKeisan() '← Privateで定義 'ここは実際の処理をプログラム End Sub |
Module2
1 2 3 4 5 6 7 |
Sub ErrSample02_02() Call JidouKeisan End Sub |
Privateで定義したプロシージャは、同じ標準モジュール内からしか呼び出すことができません。
この場合は解決方法は2つあります。
解決方法1
Private→Publicに修正して、呼び出したいプロシージャを、他のモジュールからも呼び出せるようにします。
Module1
1 2 3 4 5 6 7 |
Public Sub JidouKeisan() '← Publicに変更 'ここは実際の処理をプログラム End Sub |
解決方法2
呼び出すプログラムと、呼び出したいプロシージャを、同じ標準モジュールに記述します。
今回の例だと、呼び出し元のErrSample02_02と、呼び出し先のJidouKeisanを、同じModule1に記述します。(同じモジュール内のため、定義はPrivateのままでOKです。)
Module1
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub ErrSample02_02() '← 同じ標準モジュールに、呼び出し元・先を記述 Call JidouKeisan End Sub Private Sub JidouKeisan() 'ここは実際の処理をプログラム End Sub |
原因3. プロシージャのスペルミス
解説
意外とバカにできないのが、スペルミスです。
「タイプミスなんてしてるわけがない」という思い込みで、原因を見つけるのに時間がかかってしまうパターンです。
1 2 3 4 5 6 7 8 9 10 11 12 13 |
Sub ErrSample02_03() Call JidouKeisn '←JidouKeisanがJidouKeisnになっている End Sub Sub JidouKeisan() 'ここは実際の処理をプログラム End Sub |
解決方法
プロシージャ(sub,function)の定義とスペルをあわせましょう。
スペルミスはもったいないので、プロシージャを呼び出す時は、次の2つの方法でできる限り減らしましょう。
1.タイピングは極力しないで、コピー&ペースト
2.プロシージャ名を途中まで入力して、Ctr+Spaceで入力候補から選ぶ