VBAのマクロを実行しようとした瞬間、「コンパイルエラー: Sub または Function が定義されていません。」というダイアログが表示されて処理が止まってしまう——このエラーで悩んでいる方は多いのではないでしょうか。

特に困るのが、「どこかのサイトからコピーしたコードを貼り付けたのに動かない」「昨日まで動いていたのに突然エラーが出た」「コードをよく見ても間違いがわからない」といったケースです。

このエラーはメッセージが一見わかりにくいため原因の特定に手間取りがちですが、発生パターンは限られており、それぞれに明確な修正方法があります。本記事ではMicrosoft公式ドキュメント(Office VBA リファレンス)および信頼性の高い情報をもとに、原因・見落としがちなパターン・具体的な修正コード・参照設定の対処方法まで体系的に解説します。

目次

  1. 「SubまたはFunctionが定義されていません」とは何か
  2. 原因1:呼び出し先のプロシージャ名のスペルミス
  3. 原因2:VBA組み込み関数・メソッド・プロパティ名のスペルミス
  4. 原因3:呼び出し先のプロシージャがそもそも存在しない
  5. 原因4:呼び出し先がPrivate宣言されていて別モジュールから参照できない
  6. 原因5:シートモジュール・ThisWorkbookモジュールのプロシージャを標準モジュールから呼んでいる
  7. 原因6:参照設定が追加されていないライブラリの関数を使っている
  8. 原因7:Option Private Moduleが設定されている
  9. 原因8:プロシージャ名にスペースや禁止文字が含まれている
  10. 原因9:ブックをまたいだプロシージャ呼び出しで参照が不足している
  11. エラー箇所の素早い特定方法
  12. PrivateとPublicの違いと使い分け
  13. 参照設定の追加手順(ライブラリ別)
  14. 解決方法チェックリスト
  15. よくある質問(FAQ)

1. 「SubまたはFunctionが定義されていません」とは何か

「コンパイルエラー: Sub または Function が定義されていません。」は、VBAがコードをコンパイル(解析)する段階で、呼び出そうとしたプロシージャ(Sub・Function・Property)が見つからなかったときに発生するエラーです。

Microsoftの公式ドキュメント(Visual Basic エラーメッセージ一覧)では、このエラーの発生原因として以下の3つを挙げています。

  • 参照ダイアログボックスでそのプロジェクトへの参照を明示的に追加せずに、別のプロジェクトからプロシージャを呼び出そうとしている
  • 呼び出し元のプロシージャに表示されないプロシージャを指定している
  • 指定されたライブラリまたはコードリソースにないDLLルーチンを宣言している

より実務に即した言い方をすると、「指定した名前のSubやFunctionが、VBAから見える場所に存在しない」状態がすべての原因の共通点です。

このエラーはコンパイルエラーのため、マクロを実行する前——コードの解析段階で検出されます。エラーが発生した箇所はVBE上で青くハイライトされて表示されます。

コンパイルエラーと実行時エラーの違い:コンパイルエラーはコード実行前に検出されるため、エラーダイアログに「デバッグ」ボタンはありません。「OK」を押すとダイアログが閉じ、問題箇所が青くハイライトされた状態のVBEが表示されます。

2. 原因1:呼び出し先のプロシージャ名のスペルミス

最も頻繁に発生するパターンです。単純なスペルの書き間違いや、モジュール間のアクセスが禁止されていることが原因であることがほとんどです。プロシージャ名を1文字でも誤って記述すると、VBAはその名前のSubやFunctionを探しますが見つからないためエラーになります。

Option Explicit

' NG例:呼び出し先の名前を書き間違えている
Sub Main_NG()
    Call CalcTotalPrce   ' 「Price」を「Prce」とミスタイプ → エラー
End Sub

Sub CalcTotalPrice()    ' ← 正しい名前はこちら
    MsgBox "合計金額を計算しました。"
End Sub
Option Explicit

' OK例:呼び出し元と呼び出し先の名前を完全一致させる
Sub Main_OK()
    Call CalcTotalPrice  ' 正しい名前で呼び出す
End Sub

Sub CalcTotalPrice()
    MsgBox "合計金額を計算しました。"
End Sub

Callなしでも同様のエラーになる

VBAではCallキーワードを省略してプロシージャを呼び出すこともできます。Callを使わない場合も、スペルミスがあれば同じエラーが発生します。

' Callなしでも同様のエラーが発生する
Sub Main()
    CalcTotalPrce    ' ← Callなしでも名前が違えばエラー
    CalcTotalPrice   ' ← これが正しい
End Sub

対処法:Ctrl+Spaceの入力補完を活用する

VBEではCtrl+Spaceを押すことでコード補完が起動します。プロシージャ名を途中まで入力してCtrl+Spaceを押すと候補一覧が表示され、そこから選択することでスペルミスを防げます。また、すでに定義済みのプロシージャ名は、VBEが自動的に大文字・小文字を定義時の名前に合わせて補正するため、補正されない場合はスペルミスのサインとして活用できます。

3. 原因2:VBA組み込み関数・メソッド・プロパティ名のスペルミス

これは見落としやすいパターンです。RangaやCellssのように、プロパティ名が間違っているのですが、VBAはここで「○○(~)」を「○○という名前のプロシージャを呼び出している」と誤認します。そして「Rangaなんて名前のプロシージャは見あたらない」というエラーになります。

つまり、MsgBoxをnsgBoxと書き間違えた場合や、Rangeを引数つきでRangaと書き間違えた場合でも、このエラーが発生します。VBAがそれを「Rangaという名前の自作プロシージャの呼び出し」と解釈するためです。

Option Explicit

' NG例1:MsgBoxを「nsgBox」とミスタイプ
Sub Sample_NG_MsgBox()
    nsgBox "処理が完了しました。"   ' コンパイルエラー:SubまたはFunction...
End Sub

' NG例2:Range("A1")を「Ranga("A1")」とミスタイプ
Sub Sample_NG_Range()
    Dim v As Variant
    v = Ranga("A1").Value   ' コンパイルエラー:SubまたはFunction...
End Sub
Option Explicit

' OK例1:正しいMsgBoxの書き方
Sub Sample_OK_MsgBox()
    MsgBox "処理が完了しました。"
End Sub

' OK例2:正しいRangeの書き方
Sub Sample_OK_Range()
    Dim v As Variant
    v = Range("A1").Value
    Debug.Print v
End Sub

「ActiveSheet.Ranga(“A1”) = 100」はエラーにならない場合がある

同じ打ち間違いでも、「ActiveSheet.Ranga(“A1”)」のようにオブジェクトを前置するとプロシージャの呼び出しとは認識されないため、別のエラー(「そんな名前のプロパティはない」という主旨のエラー)になります。エラーメッセージが異なる理由はこの違いによるものです。

4. 原因3:呼び出し先のプロシージャがそもそも存在しない

ウェブの参考プログラムや、他のファイルからコピーした時などに、呼び出し先のコピーが漏れている時によく起こるエラーです。

「仮組み」として呼び出しだけ書いてプロシージャ本体をまだ作っていない場合や、別ファイルのコードをコピーする際に呼び出し先のSubやFunctionのコピーを忘れた場合に発生します。

Option Explicit

' NG例:呼び出し先のプロシージャ本体がプロジェクト内に存在しない
Sub Main_NG()
    Call FormatReport    ' FormatReportがどこのモジュールにも存在しない → エラー
    Call PrintReport     ' PrintReportもない → エラー
End Sub
Option Explicit

' OK例:呼び出し先のプロシージャ本体を同一プロジェクト内に定義する
Sub Main_OK()
    Call FormatReport
    Call PrintReport
End Sub

Sub FormatReport()
    ' 書式設定処理
    Range("A1:Z100").Font.Name = "メイリオ"
    MsgBox "書式設定が完了しました。"
End Sub

Sub PrintReport()
    ' 印刷処理
    ActiveSheet.PrintPreview
End Sub

仮組みで呼び出しだけ書く場合の対処法

開発途中でプロシージャの中身はまだ書けないが、呼び出しだけ先に書きたい場合は、空のプロシージャを先に作っておくことでコンパイルエラーを回避できます。

Option Explicit

' 開発途中:呼び出しだけ先に書く場合は空のプロシージャを定義する
Sub Main()
    Call FormatReport   ' 呼び出しは書いてある
    Call PrintReport
End Sub

' 空のプロシージャ(スタブ)を先に作っておく → コンパイルエラーを回避
Sub FormatReport()
    ' TODO: 書式設定処理を実装予定
End Sub

Sub PrintReport()
    ' TODO: 印刷処理を実装予定
End Sub

5. 原因4:呼び出し先がPrivate宣言されていて別モジュールから参照できない

他の標準モジュールにプロシージャ(Sub・Function)はちゃんと定義しているけど、Privateで宣言されているときに起こります。Privateで定義したプロシージャは、同じ標準モジュール内からしか呼び出すことができません。

'=== Module1 ===
Option Explicit

' NG例:Module1でPrivate宣言したプロシージャをModule2から呼ぼうとする
Private Sub CalcBonus()    ' ← Privateは同一モジュール内限定
    MsgBox "賞与計算を実行しました。"
End Sub
'=== Module2 ===
Option Explicit

Sub Main_NG()
    Call CalcBonus   ' コンパイルエラー:Module1のPrivateプロシージャは見えない
End Sub

解決策は2つ

解決方法は2つあります。PrivateをPublicに修正して、呼び出したいプロシージャを他のモジュールからも呼び出せるようにする方法と、呼び出すプログラムと呼び出したいプロシージャを同じ標準モジュールに記述する方法です。

'=== Module1(解決策1:PrivateをPublicに変更) ===
Option Explicit

Public Sub CalcBonus()    ' ← Publicに変更すれば他のモジュールから呼べる
    MsgBox "賞与計算を実行しました。"
End Sub
'=== Module2(解決策2:呼び出しと定義を同じモジュールにまとめる) ===
Option Explicit

Sub Main_OK()
    Call CalcBonus   ' 同じモジュール内なのでPrivateのままでもOK
End Sub

Private Sub CalcBonus()   ' Privateのまま同じモジュール内に移動
    MsgBox "賞与計算を実行しました。"
End Sub

6. 原因5:シートモジュール・ThisWorkbookモジュールのプロシージャを標準モジュールから呼んでいる

通常、標準モジュール間でのプロシージャの呼び出しは自由にできますが、シートモジュール、ThisWorkbookモジュールなどはPrivate扱いなので参照することができません。

つまり、「Sheet1」「Sheet2」「ThisWorkbook」などのモジュールに書かれたプロシージャは、宣言キーワードを何も書かなくてもPrivate相当の扱いになり、標準モジュールから Call で直接呼び出すことができません。

'=== Sheet1モジュール(シートモジュール) ===
' ※ シートモジュールのプロシージャはPrivate扱い

Sub FormatSheet1()   ' 宣言なしでもPrivate扱い
    Range("A1").Interior.Color = RGB(255, 255, 0)
End Sub
'=== Module1(標準モジュール) ===
Option Explicit

' NG例:標準モジュールからシートモジュールのプロシージャをCallで呼ぶ
Sub Main_NG()
    Call FormatSheet1   ' コンパイルエラー:シートモジュールはPrivate扱い
End Sub

' OK例:シートモジュールのプロシージャはオブジェクトを経由して呼ぶ
Sub Main_OK()
    Sheet1.FormatSheet1   ' Sheet1オブジェクトを経由すれば呼び出せる
End Sub

またはシートモジュールに書いていたプロシージャを標準モジュールに移動することでも解決します。シートモジュールには、そのシート固有のイベント(Worksheet_ChangeやWorksheet_SelectionChangeなど)のみを書き、汎用的な処理は標準モジュールに分離するのが設計のベストプラクティスです。

7. 原因6:参照設定が追加されていないライブラリの関数を使っている

ExcelVBAでは、標準のオブジェクトライブラリ以外の機能(Outlookでのメール送信・WordのVBA・RegExp正規表現・ソルバーなど)を使う場合、VBEの「参照設定」で該当ライブラリをチェックする必要があります。参照設定が追加されていないと、そのライブラリのプロシージャ・関数が「定義されていない」とみなされてエラーになります。

例えばWordのVBAでExcel関数を呼び出す処理をするときに「Excel Object Library」の参照設定が抜けていたり、Excel側からOutlookのメール送信機能を呼び出すときに「Outlook Object Library」の参照設定が抜けていたりする場合が該当します。

よくある参照設定が必要なライブラリ一覧

使いたい機能参照設定するライブラリ代表的な関数・オブジェクト
Outlookでのメール送信Microsoft Outlook *.* Object LibraryOutlook.Application・MailItem
WordのVBAからExcel操作Microsoft Excel *.* Object LibraryExcel.Application・Workbook
正規表現(RegExp)Microsoft VBScript Regular Expressions 5.5RegExp・Match・MatchCollection
ソルバー(Solver)Solver(アドイン有効化後に表示)SolverOK・SolverSolve
ファイルシステム操作(FSO)Microsoft Scripting RuntimeFileSystemObject・TextStream
Internet Explorer操作Microsoft Internet ControlsInternetExplorer
AccessのVBAからDAO操作Microsoft DAO *.* Object LibraryDAO.Database・DAO.Recordset

参照設定の追加手順(詳細)

参照設定の追加は以下の手順で行います。

  • VBE(Alt+F11)を開く
  • メニューバーの「ツール」→「参照設定」をクリック
  • 「参照可能なライブラリ ファイル」の一覧から追加したいライブラリのチェックボックスをオンにする
  • 「OK」をクリックして設定を保存
  • 一覧に表示されない場合は「参照」ボタンをクリックし、.dllや.xlam などのファイルを直接指定する

ソルバーを使う場合の注意点:ソルバーはExcelのアドインとして有効化してから参照設定を行う必要があります。Excelの「ファイル」→「オプション」→「アドイン」→「Excelアドイン」→「ソルバー アドイン」にチェックを入れてOKをクリックした後、VBEの参照設定に「Solver」が表示されるようになります。

Early BindingとLate Bindingの違い

外部ライブラリの使い方には「Early Binding(参照設定あり)」と「Late Binding(CreateObjectを使用)」の2通りがあります。

'--- Early Binding(参照設定が必要)---
' VBEの参照設定で「Microsoft Scripting Runtime」を追加した場合
Option Explicit

Sub EarlyBindingExample()
    Dim fso As FileSystemObject   ' 型を指定できる(入力補完が効く)
    Set fso = New FileSystemObject
    MsgBox fso.GetBaseName("C:\data\sales.xlsx")  ' → "sales"
    Set fso = Nothing
End Sub
'--- Late Binding(参照設定不要)---
' CreateObjectを使えば参照設定なしで外部ライブラリを利用できる
Option Explicit

Sub LateBindingExample()
    Dim fso As Object             ' 型はObjectにする
    Set fso = CreateObject("Scripting.FileSystemObject")  ' 実行時に生成
    MsgBox fso.GetBaseName("C:\data\sales.xlsx")  ' → "sales"
    Set fso = Nothing
End Sub

Late Bindingはファイルを他の環境に配布する際に参照設定が不要になるメリットがありますが、入力補完が効かず開発効率が下がります。開発中はEarly Bindingで行い、配布前にLate Bindingに書き換える方法がよく使われます。

8. 原因7:Option Private Moduleが設定されている

Option Private Moduleはモジュールレベルのステートメントで、そのモジュール内のすべてのプロシージャをプロジェクト外から隠す効果があります。Microsoftの公式ドキュメントでは「Option Private Module が有効の場合、モジュール内のプロシージャを他のプロジェクトで使用することはできません。」と定義されています。

Option Private ModuleはExcelのマクロ実行(「マクロ」ダイアログからの実行)でもそのプロシージャが一覧に表示されなくなるため、意図せず設定されていると「なぜか実行できない」という現象として現れます。

'=== Module1 ===
Option Explicit
Option Private Module   ' ← これがある場合、プロジェクト外から呼び出せない

Public Sub HiddenSub()   ' Publicでも外部からは呼び出せない
    MsgBox "このSubはOption Private Moduleで隠されています。"
End Sub

他のプロジェクトやブックから呼び出す必要がなければ問題ありませんが、意図せず設定されている場合は Option Private Module の行を削除してください。

9. 原因8:プロシージャ名に禁止文字・スペースが含まれている

VBAのプロシージャ名には使用できない文字のルールがあります。スペース・ピリオド・感嘆符・@・&・$・# などの記号を含めると定義時にエラーになりますが、もし何らかの形でこれらを含む名前で呼び出そうとした場合も「SubまたはFunctionが定義されていません」エラーの原因になります。

' VBAのプロシージャ名の命名規則
' ----------------------------------------
' 使える   :英字・日本語・数字(先頭は数字以外)・アンダースコア(_)
' 使えない  :スペース・ピリオド(.)・感嘆符(!)・@・&・$・#
' 最大文字数:255文字
' 大文字小文字は区別しない(FuncAとfuncaは同じ名前とみなされる)
' ----------------------------------------

' OK例:有効なプロシージャ名
Sub CalcMonthlyTotal()      ' 英字
End Sub
Sub 月次合計の計算()          ' 日本語
End Sub
Sub Calc_2024_Total()       ' 数字・アンダースコア
End Sub

' NG例:無効なプロシージャ名(定義時にエラー)
' Sub Calc Total()           ' スペースは不可
' Sub Calc.Total()           ' ピリオドは不可
' Sub 2024Calc()             ' 先頭が数字は不可

10. 原因9:ブックをまたいだプロシージャ呼び出しで参照が不足している

参照ダイアログボックスでそのプロジェクトへの参照を明示的に追加せずに、別のプロジェクトからプロシージャを呼び出そうとしていることが原因のケースです。別のブック(別のVBAプロジェクト)に定義されたプロシージャを呼び出すには、参照設定でそのブックへの参照を追加するか、ブック名を明示して呼び出す必要があります。

' 別ブックのプロシージャを呼び出す場合の書き方
' (別のExcelファイル「共通マクロ.xlsm」のModule1にあるSendReportを呼ぶ場合)

' NG例:参照設定なしで直接呼ぶ → エラー
Sub Main_CrossBook_NG()
    Call SendReport    ' 別ブックにあるので見えない → エラー
End Sub

' OK例:Applicationオブジェクトを通じてRunメソッドで呼ぶ
Sub Main_CrossBook_OK()
    Application.Run "'共通マクロ.xlsm'!SendReport"
End Sub

11. エラー箇所の素早い特定方法

コンパイルエラーが発生した際は、以下の手順でエラー箇所を素早く特定できます。

11-1. OKボタンを押してハイライト箇所を確認する

エラーダイアログが表示されたら「OK」ボタンをクリックしてください。VBEが表示され、問題のある部分(呼び出せなかったSubやFunction名)が青くハイライトされます。ハイライトされた名前がどのプロシージャを指しているかを確認します。

11-2. プロジェクト全体をコンパイルして一括確認する

VBEのメニューから「デバッグ」→「VBAProjectのコンパイル」を実行すると、プロジェクト全体のコンパイルエラーを実行前にまとめて確認できます。複数のモジュールに問題がある場合でも、1つずつ順番に検出されます。

' VBEメニュー → デバッグ → VBAProjectのコンパイル
' ショートカットキー:なし(メニューから操作)
' → エラーがある場合:最初のコンパイルエラー箇所が青くハイライトされる
' → エラーがない場合:何も表示されず、コンパイル成功を意味する

11-3. Ctrl+Fでプロジェクト全体を検索する

VBEで「Ctrl+F」(検索)を開き、「カレントプロジェクト」を検索対象にして、エラーになったプロシージャ名を検索すると、そのプロシージャがプロジェクト内に存在するかどうかを素早く確認できます。

' VBEの検索機能の活用
' Ctrl + F → 「検索と置換」ダイアログを開く
' 「検索範囲」を「カレントプロジェクト」に変更
' → プロジェクト内のすべてのモジュールから該当名を検索できる

12. PrivateとPublicの違いと使い分け

このエラーの多くはPrivate/Publicのアクセス指定子の理解不足が関係しています。VBAにおけるPrivateとPublicの違いをしっかり把握しておくことがエラーの予防につながります。

宣言呼び出せる範囲マクロ一覧への表示推奨用途
Sub Sample()
(宣言なし)
プロジェクト内のすべてのモジュール表示される外部から呼び出す可能性があるメインの処理
Public Sub Sample()プロジェクト内のすべてのモジュール(宣言なしと同じ)表示される外部から呼び出す可能性があるメインの処理(明示的に公開)
Private Sub Sample()同一モジュール内のみ表示されない内部処理の補助関数・ユーザーに直接実行させたくない処理

設計の観点から言うと、外部から呼び出される必要のないプロシージャはPrivateにして、Public(または宣言なし)は最小限にすることがコードの品質を高めるベストプラクティスです。ただし誤ってPrivateにしてしまうとこのエラーの原因になるため、現状のコードが動かない場合はまずPublicに変更して確認してみてください。

14. 解決方法チェックリスト

「コンパイルエラー: Sub または Function が定義されていません。」が発生したとき、上から順番に確認してください。

  • エラーダイアログの「OK」を押し、青くハイライトされた呼び出し名を確認する
  • ハイライトされた名前のスペルが、定義されているプロシージャ名と1文字も違わず一致しているか確認する
  • VBA組み込み関数・メソッド・プロパティ名のスペルが正しいか確認する(MsgBox・Range・Cells・Worksheetsなど)
  • 呼び出しているSubやFunctionが、プロジェクト内のどこかのモジュールに実際に定義されているかCtrl+Fで検索して確認する
  • 呼び出し先がPrivate宣言されていて、別モジュールから参照できない状態になっていないか確認する
  • 呼び出し先がシートモジュール・ThisWorkbookモジュールに書かれていないか確認し、必要なら標準モジュールに移動するか「Sheet1.プロシージャ名」の形式で呼ぶ
  • 外部ライブラリ(Outlook・FSO・RegExp・ソルバーなど)の関数を使っている場合は、VBEの「ツール」→「参照設定」で該当ライブラリにチェックが入っているか確認する
  • Option Private Moduleが意図せず記述されていないかモジュール先頭を確認する
  • 別ブックのプロシージャを呼び出す場合は、参照設定またはApplication.Runメソッドを使って呼び出す
  • VBEメニューの「デバッグ」→「VBAProjectのコンパイル」を実行してプロジェクト全体のエラーを一括確認する

15. よくある質問(FAQ)

Q1. 同じプロジェクト内に定義したのに「SubまたはFunctionが定義されていません」が出ます。

最も多い原因は呼び出し名のスペルミスです。VBEで「Ctrl+F」を使い「カレントプロジェクト」を対象に呼び出したいプロシージャ名を検索してください。ヒットしない場合はスペルが異なっている証拠です。ヒットした場合は、そのプロシージャがPrivate宣言されていないか、または別モジュールからはアクセスできないシートモジュール内に書かれていないか確認してください。

Q2. ソルバーを使うマクロをコピーしたら「SubまたはFunctionが定義されていません」になりました。

コピー先の環境でソルバーの参照設定が追加されていないことが原因です。まずExcelの「ファイル」→「オプション」→「アドイン」でソルバーアドインを有効化してから、VBEの「ツール」→「参照設定」で「Solver」にチェックを入れてください。コピー元でチェックしていても、コピー先では再設定が必要です。

Q3. プロシージャ名が正しくて参照設定も問題ないのにエラーが出ます。

まずVBEメニューの「デバッグ」→「VBAProjectのコンパイル」を実行してすべてのエラーを洗い出してください。それでも原因が不明な場合は、そのプロシージャをまったく新しいモジュールに移してから再コンパイルしてみてください。稀にモジュール自体のデータ破損が原因でエラーになるケースがあります。

Q4. Callキーワードは使わなくてもいいですか?

VBAではCallキーワードを省略してプロシージャを呼び出すことができます。Call SampleSub()SampleSub は同じ動作です。ただしCallを省略する場合は引数を括弧で囲まないことが慣例です(括弧で囲むとByValで渡されるため動作が変わる場合があります)。どちらを使っても「SubまたはFunctionが定義されていません」のエラーは、呼び出し名が存在しないという原因が同じです。

Q5. シートモジュールに書いたSubをボタンに登録できません。

Excelのボタン(フォームコントロールやActiveXコントロール)に登録できるマクロは、標準モジュールに書かれた引数なし・Public(または宣言なし)のSubプロシージャに限られます。シートモジュールやThisWorkbookモジュールに書かれたSubはボタンから直接実行できないため、標準モジュールにラッパーのSubを作成してシートモジュールのSubを呼び出すか、処理全体を標準モジュールに移動してください。

まとめ

「コンパイルエラー: Sub または Function が定義されていません。」は、呼び出そうとしたSubやFunctionがVBAから見える場所に存在しないか、アクセスできない状態にあることが根本的な原因です。Microsoftの公式ドキュメントにも、プロシージャ名のスペルミス・スコープの制限・参照不足の3つが主要原因として挙げられています。

実務で特に多いのは、呼び出し名のスペルミス・PrivateプロシージャをPublicに変更し忘れた・コードをコピーした際に呼び出し先のプロシージャを含め忘れた・参照設定の追加を忘れたの4パターンです。

エラーが発生したらまずOKを押してハイライト箇所を確認し、Ctrl+Fで名前を検索して存在を確認する——この2ステップだけで大半のケースは原因を特定できます。本記事のチェックリストをブックマークしておき、エラーに遭遇した際の解決フローとして活用してください。