Vba エラーの種類: デバッグと解決策
他のプログラミング言語と同様、VBA でもエラーが発生すると不運なので、何としてもエラーに対処する必要があります。これらは、不適切なコーディング、不可能な演算 (ゼロによる除算など)、または予期しないエラーなど、さまざまな原因から発生する可能性があります。
これに対処する最善の方法は、コードで達成できる可能性のあるすべての結果をよく理解することです。以下の例を見てください。選択したセルの値を使用して数値の平方根を計算する VBA コードがあります。
Sub Square_Root() ActiveCell. Value = ActiveCell. Value ^ (1 / 2) End Sub
ただし、アクティブ セルに数値以外の値が含まれている場合は、次のような実行時エラーが発生します。
VBA のエラー パラメーター (エラー キャッチ)
VBAオプションでは、コードを書き始める前にエラーを処理する設定を行うことができます。 VBA 設定を開くには、ツール ➤ オプション ➤ 一般 ➤ エラー検出に移動します。ここには使用できるオプションが 3 つあります。
- すべてのエラーで停止: このオプションを有効にすると、あらゆる種類のエラー処理手法を使用した場合でも、VBA はすべての種類のエラーでコードを停止します。
- クラス モジュールの改ざん: このオプションを使用すると、VBA はどの手法でも処理されないすべてのコードを停止します。また、ユーザーフォームなどのオブジェクトを使用している場合は、それらのオブジェクトにも侵入して、エラーのある正確な行を強調表示します。
- 未処理エラーで中断: これは、エラー処理手法を使用していないすべてのエラーを把握し、すべての未処理エラーのコードを停止するのに役立つデフォルト設定です。 (ただし、ユーザーフォームなどのオブジェクトを使用する場合、オブジェクト内のエラーの原因となっている行は強調表示されず、そのオブジェクトを参照する行のみが強調表示されます)。
VBA エラーの種類
VBA エラーを理解するには、エラーを 4 つのカテゴリに分類することができます。以下では、これらのタイプのエラーについて説明します。
1. 構文エラー
VBA コードを作成するときは、特定の構文に従う必要がありますが、それを無視したり、正しく記述しなかった場合、SYNTAX エラー (言語エラーとも呼ばれます) が発生する可能性があります。これは、コードを書いているときに行うタイプミスのようなものです。
VBA は、エラー メッセージを表示してこれらのエラーを報告するのに役立ちます。 VB エディターで「自動構文チェック」が有効になっていることを確認するだけです。
[ツール] ➤ [オプション] に移動し、[自動構文チェック] ボックスを必ずオンにします。これにより、SYNTAX エラーが発生するたびに、VBA によってエラー メッセージが表示されます。
ただし、[自動構文チェック] が無効になっている場合でも、VBA はエラーのあるコード行を強調表示しますが、エラー メッセージは表示されません。
2. コンパイルエラー
これは、アクティビティを実行するコードを作成したが、そのアクティビティが無効であるか、VBA で実行できない場合に発生します。最も良い例は、IF ステートメントを使用するコードがあるが、ステートメントの最後に END IF を追加し忘れたため、この VBA を実行するとコンパイル エラー メッセージが表示される場合です。
これとは別に、コンパイル エラーの例は他にもあります。
- Next なしで For を使用する ( For Next )。
- 末尾を選択せずに選択します(場合を選択)。
- 「 Explicit Option 」を有効にした場合は変数を宣言しないでください。
- 存在しないサブ/関数を呼び出しています。
3. 実行時エラー
コードを実行するとランタイム エラーが発生します。上で共有した、コードが数値の平方根を計算する例を思い出してください。
コードの実行中にランタイム エラーが発生すると、コードが停止され、エラー ダイアログ ボックスが表示されます。このエラー ボックスには、発生したエラーの性質が表示されます。指定した場所からブックを開くコードを作成したが、そのブックが誰かによって移動または削除されたとします。
したがって、コードを実行すると、この場所にこのファイルが見つからないため、VBA はランタイム エラーを表示します。実行時エラーで表示されるメッセージには、エラーの理由を理解するのに役立つ理由が説明されています。
実行時エラーが発生すると、コードの実行が停止します。 「デバッグ」ボタンをクリックすると、このエラーを含むコード行が黄色で強調表示されて表示されます。または、「終了」ボタンをクリックしてコードの実行を停止し、エラー メッセージを閉じることもできます。
4. 論理エラー
これはエラーではなく、コード作成時のエラーです。このようなタイプのエラーは、検出して修正するときに問題が発生することがあります。
コードを作成していて、変数を宣言するときに間違ったデータ型を使用したか、間違った計算手順を使用したとします。この場合、コードは正常に動作し、このエラーは簡単には見つかりません。この種の問題に対処する最善の方法は、コードの各行を 1 つずつ実行することです。
VBA でのデバッグ ツールの使用
VBA は、コードをデバッグし、コードからバグを削除するための一連のツールを提供します。
1.VBAプロジェクトをコンパイルします。
Visual Basic Editor には、コードの完成後にすぐに使用できるオプションがあります。これらのコンパイル オプションはコードの各行を分析し、コードにエラーがある場合はメッセージ ボックスを表示します。
注: [VBA のコンパイル] オプションでは、構文エラーとコンパイル エラーのみがトレースされ、実行時エラーはトレースされません。これらのエラーはコードの実行中にのみ発生するためです。 VBA プロジェクトのコンパイルを使用するには、 ➤ デバッグ ➤ VBA プロジェクトのコンパイルに移動します。
「VBA プロジェクトのコンパイル」を実行し、コードにエラーがなくなると、オプションがグレー表示になります。
2. コードの各行を 1 つずつ実行します
これが私のやり方です。コードが完成したら、それを 1 行ずつ実行して、エラーがあるかどうかを確認します。これには時間がかかる場合がありますが、すべてのエラー (構文、コンパイル、実行) を解決するのに役立ちます。
[デバッグ ツールバー] には、コードを 1 行ずつ実行するために使用できる [ステップイン] ボタンがあります。または、F8 キーを押して 1 行を実行し、もう一度押すとコードの次の行を実行できます。
「On ERROR」ステートメントを使用した VBA エラーの処理
コードをチェックし、利用可能なすべてのデバッグ方法で考えられるエラーを見つけることが重要です。しかし、最善かつ最も効率的な方法は、エラーを処理し、実行時にコードを完璧にするエラー処理命令を作成することです。これらのステートメントを調べてみましょう。 VBA コードでエラーが発生した場合、このエラーを処理する最善の方法は次のとおりです。
- VBA にエラーを無視させてコードを実行させます。
- エラーが発生したときに特別な命令セットを実行させます。
どちらのソリューションでも、「On Error」ステートメントを使用できます。以下に、使用できる 4 つの「エラー時」ステートメントを示します。それでは、各ステートメントを 1 つずつ見てみましょう。
1. 間違えたらやり直し
この単純なコード行により、エラーが発生しても VBA はコードの実行を継続できます。アイデアは単純です。実行中にエラーが検出された場合は、コードの次の行に移動します。
以下のコードには 2 行のコードがあります。
- 最初の行は、セル A1 の値が 25 を 0 で割った値であることを示しています。
- 2 行目は、セル値 A2 が 10 を 5 で割ったものであることを示しています。
オンラインのコードに問題があります。ご存知のとおり、何かを 0 で割ると、結果はエラーになります。したがって、このコードを実行すると、VBA は「実行時エラー ’11’ ゼロ除算」というエラー メッセージを表示し、実行を停止します。
ただし、コードの先頭に「On Error Resume Next」を追加してコードを実行すると、VBA はエラーが発生したコード行を無視して 2 行目に進み、その値をセル A2 に追加します。
Sub myDivide() On Error Resume Next Range ("A1"). Value = 25 / 0 Range ("A2"). Value = 10 / 5 End Sub
したがって、どこかでエラーが発生してもコードを実行したい場合は、コード内で「On Error Resume Next」ステートメントを使用するだけです。
ただし、もう 1 つ注意すべき点があります。それは、その後に発生するエラーのみが無視されるということです。
5 行目でエラーが発生し、8 行目に「On Error Resume Next」を追加したとします。このエラーはスキップされません。したがって、最善の方法は、プロシージャのコードの最初の行として追加することです。
2.GoTo0エラーの場合
これは、エラーが発生するとコードの実行を停止する VBA のデフォルトの動作です。
まあ、「On Error GoTo 0」を使用してもコードに違いはありません。 VBA はコードを停止し、エラーの説明を含むメッセージを表示します。では、なぜわざわざ使用する必要があるのでしょうか?賢い質問です。上の「 On Error Resume Next 」で使用した例を使用してみましょう。
このコードでは、エラーが発生するたびに、VBA はコードの次の行を取得して実行しますが、エラー メッセージは表示されません。しかし、コード内にさらに多くの行があり、コードにエラーがあった場合にそれらの行を超えたくないとしましょう。
したがって、コードの 2 行目の後に「On Error GoTo 0」と入力すると、エラーが発生するたびにエラー メッセージを表示する VBA のデフォルトのエラー ハンドラーが復元されます。
3.GoToエラーの場合【ラベル】
建物内で緊急時に行ける場所を考えてみましょう。同様に、「On Error GoTo [Label]」を使用すると、メイン コード内にエラーを処理する別のコード ブロックを作成するだけで済みます。
実際、「On Error GoTo [Label]」は、エラーを処理するためのはるかに優れた便利な方法です。以下のコードには、「On Error GoTo Oh!」があります。この行の宣言では、「Oh!」という単語が表示されます。エラー」というラベルです。
コードの最後を見ると、ラベル名で始まり、コード上のメッセージを含むメッセージ ボックスのコードが続いています。
さて、エラーが発生するとどうなるかというと、VBA は「Oh!」というラベルにジャンプします。エラー」と表示され、そのラベルの後にあるコードのブロックが実行されます。
ただし、注意する必要があることが 1 つあります。エラーが発生しない場合は、コード内にあるラベルが実行されるということです。行う必要があることが 2 つあります。
- まず、コードの最後にエラー タグを必ず追加してください。
- 次に、エラー ラベルの前に「Exit Sub」を追加します。
これにより、どちらの状況でもメリットが得られます。エラーが発生し、VBA が指定したラベルに切り替わった場合、ラベル自体からコードへのコードのみが存在するとします。エラーが発生しない場合、ラベルの前にある「Exit Sub」ステートメントは、エラー ラベルを実行せずにプロシージャを終了します。
4. GoToエラーの場合 -1
本題に入る前に、皆さんと共有したいことがあります。コードでエラーが発生すると、VBA はこのエラー ログをメモリに保存し、ルーチンが完了したときにのみクリアします。
ああ、VBA!今を生きる
VBA コードで 2 番目のエラーを処理するには、VBA のメモリから最初のエラーをクリアする必要があります。以下のコードには、2 つの異なるコード ブロックからのエラーを処理する 2 つの「On Error GoTo [Label]」ステートメントがあります。
ただし、このコードを実行すると、2 番目のエラーが発生したときに、VBA は設定したラベルにジャンプせず、代わりに「型が一致しません」というエラー メッセージが表示されます。
Sub Square_Root() On Error GoTo myError1 Range ("A1"). Value = Range ("A1"). Value ^ (1 / 2) myError1: MsgBox "There's some problem with the value you have in the cell A1." On Error GoTo myError2 Range ("A2"). Value = Range ("A2"). Value ^ (1 / 2) myError2: MsgBox "There's some problem with the value you have in the cell A2." End Sub
この問題を解決するには、「On Error GoTo -1」を使用します。これにより、VBA は現在のエラーをストレージから削除できます。
Sub Square_Root() On Error GoTo myError1 Range("A1").Value = Range("A1").Value ^ (1 / 2) myError1: MsgBox "There's some problem with the value you have in the cell A1." On Error GoTo -1 On Error GoTo myError2 Range("A2").Value = Range("A2").Value ^ (1 / 2) myError2: MsgBox "There's some problem with the value you have in the cell A2." End Sub
このコードを実行すると、「On Error GoTo -1」によってメモリからエラーが削除され、VBA は 2 番目のステートメントのエラーを必要に応じて処理します。
VBA でエラーを処理するには他に何を知っておく必要がありますか?
エラー処理テクニックを使用する以外にも、エラーをより適切に処理するために使用できるものがいくつかあります。
オブジェクトエラー
コードの実行中にエラーが発生した場合、Err オブジェクトを使用してエラーの詳細を取得できます。 Err オブジェクトで使用できるプロパティとメソッドがいくつかあります。一つずつ学んでいきましょう。
プロパティ
Err オブジェクトで使用できるプロパティは次のとおりです。
- Err.Number : エラーが発生した場合、Err オブジェクトに数値が格納されます。以下のコードでは、エラーが発生すると、メッセージ ボックスにエラー番号が表示されます。
- Err.Description : このプロパティには、エラーの理由を理解するのに役立つエラーの説明が表示されます。
- Err.Source:このプロパティは、どのプロジェクトでエラーが発生したかを示します。
- Err.HelpContext:このプロパティは、ヘルプ ファイル内のエラーのヘルプ コンテキスト ID を返します。
- Err.HelpContext:これは、ヘルプ ファイルの場所を示す文字列値です。
通常、エラー処理手法を使用してエラーに対処する場合、コード内で Err オブジェクトをあまり使用しません。ただし、以下はそれを使用する簡単な例です。
Sub Square_Root() On Error GoTo myError1 Range("A1").Value = Sqr(Range("A1").Value) Exit Sub myError1: MsgBox "There's some problem with the value you have in the cell A1." & vbCrLf & _ "Error Number: " & Err.Number & vbCrLf & _ "Error Description: " & Err.Description End Sub
上記のコードを実行すると、エラーが発生した場合、エラー番号とエラーの説明を含むメッセージ ボックスが表示されます。
メソッド
Err Object では 2 つのメソッドも使用できます。
- Err.Clear:このメソッドは、VBA メモリからエラー番号とエラーの説明をクリアします (エラーを完全にリセットしないため、これは「On Error GoTo -1」とは異なります)。
- Err.Raise:このメソッドを使用すると、コード内で意図的にランタイム エラーを生成できます。従うべき構文は次のとおりです。
Err .Raise [番号]、[ソース]、[説明]、[ヘルプ ファイル]、[ヘルプ コンテキスト]
エラー処理に関する簡単なヒント
VBA エラーをより適切に処理するために使用できる簡単なヒントをいくつか紹介します。
- 「エラー時再開」は、エラーが発生していることが確実にわかっており、エラーのあるコード行をスキップしても問題なく次の行に進んでも問題がない場合にのみ使用してください。
- 実行時エラーに対処する最善の方法は、「エラー ハンドラー」と「エラー時 GoTo [ラベル]」を使用することです。これにより、エラーが発生するたびに通知が届きますが、厄介なエラー メッセージは表示されません。
- エラー ハンドラーを使用するときは、必ず最初に「Exit Sub」を使用してください。
関連するチュートリアル
- VBA オーバーフロー エラー (エラー 6)
- VBA ランタイム エラー (エラー 1004)
- VBA インデックス実行エラーが範囲外です (エラー 9)
- VBA タイプ非互換エラー (エラー 13)
- VBA メモリ不足エラー (エラー 7)