VBA で Try-Catch を使用する

Glen Alfaro 2023年10月8日
  1. VBA で On Error Resume Next を使用してエラーを処理する
  2. VBA で On Error GoTo 0 を使用してエラーを処理する
  3. VBA で On Error GoTo [Label] を使用してエラーを処理する
VBA で Try-Catch を使用する

Try-Catch メソッドは、コンピュータープログラミングで内部エラーが発生したときにプログラムがクラッシュするのを防ぎます。システムエラーを防ぎ、コード実行のスムーズな流れを実現するのに役立ちます。

ただし、他のプログラミング言語とは異なり、VBA には Try-Catch ブロックがありません。良い面としては、エラー処理手順用に明示的に設計された回避策があります。

この記事では、VBA でのエラー処理手順について、VBA プロジェクトでエラー処理スキームを実装するのに役立ついくつかのサンプルとともに説明およびデモンストレーションを行います。

エラーハンドラーはコードの重要な部分です。VBA コンパイラが処理できない場合、彼らは私たちの頼りになる人物です。

以下に、VBA エラー処理方法を示します。

  1. On Error Resume Next - 発生したエラーを無視し、コードは実行を継続します。
  2. On Error GoTo 0 - エラーの原因となった行のコードを停止し、エラーを説明するメッセージボックスを表示します。
  3. エラー時 GoTo [ラベル] - コードにエラーが発生した場合に実行する処理を指定できます。

これらのエラー処理ルーチンのすべてについて、以下で詳しく説明します。

VBA で On Error Resume Next を使用してエラーを処理する

このエラーハンドラにより、コンパイラはエラーを無視して次のコード行を実行できます。実装に複雑なコードを必要としないため、VBA で頻繁に使用されるエラーハンドラです。

ただし、このエラーハンドラを使用する場合は、エラーが無視されるため、注意が必要です。これらの検出されないエラーにより、コードの実行が計画どおりに実行されない場合があります。

On Error Resume Next は、発生する可能性のあるエラーの種類を知るのに最適です。そして、これらのエラーを無視しても安全だと思われる場合は、これを使用できます。

以下のコードブロックは、ゼロによる除算が数学的に許可されていないため、エラー処理ルーチンなしでエラーを出力します。

Sub DivideNumbers()

Dim x,y,z as integer

x = 10/4
y = 15/0
z= 2/5

Debug.Print x & vbNewLine & y & vbNewLine & z

End Sub

DivideNumbers 出力:

Error: ! Runtime Error '11':
         Division by Zero

On Error Resume Next エラーハンドラの使用:

Sub DivideNumbers()
    On Error Resume Next
 
Dim x, y, z As Integer

x = 10 / 4
y = 15 / 0
z = 2 / 5

Debug.Print x & vbNewLine & y & vbNewLine & z

End Sub

DivideNumbers 出力:

2.5

0

DivideNumbers 出力は、Division by Zero エラーがその行で発生したため、2 番目の行がスキップされたことを示しています。

VBA で On Error GoTo 0 を使用してエラーを処理する

On Error GoTo 0 エラーハンドラは、コンパイラのデフォルトのエラー動作をリセットします。

では、なぜまだそれを使用するのですか?On Error GoTo 0 エラーハンドラは、On Error Resume Next エラーハンドラによって引き起こされるエラーが検出されないリスクに対処します。したがって、On Error GoTo 0 は通常、On Error Resume Next と組み合わせて使用​​され、エラーが発生しないコードセクションでエラー検出を有効にします。

より適切な説明については、以下のコードブロックを参照してください。

Sub ErrorSub()
    On Error Resume Next

'An error could happen in this area but will not be detected.

    On Error Goto 0

'Once an Error occurs, an error message will appear.

End Sub

より良い例については、以下のコードブロックを参照してください。

Sub DivideNumbers()
    On Error Resume Next

Dim x, y, z, a, b, c

x = 3 / 2
y = 0 / 0
z = 2 / 6

Debug.Print x & vbNewLine & y & vbNewLine & z
    On Error GoTo 0

a = 8 / 7
b = 2 / 0
c = 2 / 7

Debug.Print a & vbNewLine & b & vbNewLine & c
End Sub

DivideNumbers 出力:

1.5
0.333333333333333

次に、コードの 2 番目の部分で On Error Resume Next が、On Error GoTo 0 によって無効にされたため、エラーが発生しました。

Error: ! Runtime Error '11':
         Division by Zero

VBA で On Error GoTo [Label] を使用してエラーを処理する

上記の 2つのエラーハンドラーはエラーを処理しません。エラーをスキップまたは無視しました。3 番目のエラーハンドラーである On Error GoTo [Label] を使用すると、エラーを処理し、エラーが発生したときに実行するアクションを選択できます。

On Error GoTo [Label] の使用にはいくつかのベストプラクティスがあります。1つはエラーが発生したときにコードの実行を終了すること、もう 1つはエラーを修正してから再試行することです。以下の例は、On Error GoTo [Label] の使用法を示しています。

以下のコードブロックは、エラーが発生したときにコードを自動的に終了します。

Sub DivideNumbertoNumber()
    On Error GoTo ErrHandler

Dim i As Integer

For i = 5 To -5 Step -1
Debug.Print i / i

Next i

ErrHandler:

End Sub

DivideNumbertoNumber 出力:

 1 
 1 
 1 
 1 
 1 

ii で割ると、0 を 0 で割ったことになり、オーバーフローが発生するため、i = 0 のときにコードの実行が停止しています。

次の例では、エラーが発生した場合に Immediate Window で出力する方法を示します。Err.Description プロパティを使用して、実際のエラーを出力することもできます。

Sub DivideNumbertoNumber()
    On Error GoTo ErrHandler

Dim i As Integer

For i = 5 To -5 Step -1
Debug.Print i / i

Next i

Exit Sub

ErrHandler:
Debug.Print "An Error occured at i is equal to " & i & vbNewLine & "Error Type: " & Err.Description

End Sub

DivideNumbertoNumber 出力:

 1 
 1 
 1 
 1 
 1 
An Error occured at i is equal to 0
Error Type: Overflow

エラーが発生しなかった場合に備えて、サブルーチンが ErrHandler に到達する前にサブルーチンを終了するために、Exit SubErrHandler の前に配置されていることに注意してください。Exit Sub が挿入されていない場合、エラーがなくてもコンパイラは ErrHandler を実行します。