Share via


Visual Basic の構造化例外処理の概要

Visual Basic は、構造化例外処理をサポートしています。構造化例外処理を使うと、信頼性が高く包括的なエラー ハンドラーによって、プログラムの作成および管理を行うことができます。 構造化例外処理とは、実行時にエラーの検出および処理を行うためのコードであり、制御構造 (Select Case や While に似た制御構造) と、例外、コードの保護ブロック、およびフィルターが組み合わされています。

Try...Catch...Finally ステートメントを使用すると、エラーが発生する可能性のあるコードのブロックを保護できます。 例外ハンドラーを入れ子にすることもできます。この場合、それぞれのブロックで宣言した変数は、ローカル スコープを持ちます。

ビデオへのリンク について、関連するビデオ デモを参照してください方法は i:未処理の例外を電子メールか。

Try...Catch...Finally ステートメント

Try...Catch...Finally ステートメントの構造体を、次のコードに示します。

Try
    ' Starts a structured exception handler.
    ' Place executable statements that may generate 
    ' an exception in this block.
Catch '[optional filters]
    ' This code runs if the statements listed in 
    ' the Try block fail and the filter on the Catch statement is true.
'[Additional Catch blocks]
Finally
    ' This code always runs immediately before
    ' the Try statement exits.
End Try
' Ends a structured exception handler.

Try...Catch...Finally 例外ハンドラーの Try ブロックには、例外が監視されるコードのセクションが含まれています。 このセクションの実行中にエラーが発生した場合、そのエラーに一致する条件が見つかるまで、Try...Catch...Finally 内のそれぞれの Catch ステートメントが Visual Basic によって調べられます。 一致が見つかった場合、その Catch ブロックの最初の行に制御が移ります。 一致する Catch ステートメントが見つからなかった場合は、例外が発生したブロックの外側にある Try...Catch...Finally ブロックの Catch ステートメントが検索されます。 このプロセスは、現在のプロシージャで一致する Catch ブロックが見つかるまで、スタック全体にわたって続けられます。 一致が見つからなかった場合は、エラーが生成されます。

Finally セクション内のコードは、Catch ブロック内のコードが実行されたかどうかに関係なく、常に最後 (エラー処理ブロックがスコープを失う直前) に実行されます。 Finally セクションには、クリーンアップ コード (ファイルを閉じたりオブジェクトを解放したりするコードなど) を配置します。 例外をキャッチする必要はないけれども、リソースをクリーンアップする必要がある場合、Finally セクションではなく、Using ステートメントを使用します。 詳細については、「Using ステートメント (Visual Basic)」を参照してください。

Catch ブロックにおけるエラーのフィルター処理

Catch ブロックで特定のエラーをフィルター処理するには、3 とおりの方法があります。 まず、次のように、例外のクラス (次の例では ClassLoadException) に基づいてエラーをフィルター処理する方法があります。

Try
    ' "Try" block.
Catch e as ClassLoadException
    ' "Catch" block.
Finally
    ' "Finally" block.
End Try

ClassLoadException エラーが発生すると、指定した Catch ブロック内のコードが実行されます。

エラーをフィルター処理する 2 番目の方法では、Catch セクションで任意の条件式をフィルター処理できます。 この型の Catch フィルターは、たとえば次のコードのように、特定のエラー番号をテストする場合などによく使用されます。

Try
   ' "Try" block.
Catch When ErrNum = 5 'Type mismatch.
   ' "Catch" block.
Finally
   ' "Finally" block.
End Try

一致するエラー ハンドラーが Visual Basic で見つかると、そのハンドラー内のコードが実行され、Finally ブロックに制御が渡されます。

注意

例外を処理するために Catch ブロックを見つけるときには、一致が見つかるまで各ブロックのハンドラーが評価されます。 これらのハンドラーは関数の呼び出しである場合もあるため、予期しない副作用が起こることがあります。たとえば、そのような呼び出しによってパブリック変数が変更され、後でその変数が、最終的に例外を処理する別の Catch ブロックのコードで使用される場合があります。

3 番目の方法として、1 番目と 2 番目の方法を組み合わせ、両方を使用して例外処理を行うこともできます。 Catch ステートメントの特定性を最大から最小に移行する必要があります。 Catch ブロック自体は、Exception から派生したすべての例外をキャッチします。したがって、常に Finally の前の、最後のブロックである必要があります。

Try…Catch ブロックの分岐

Catch ブロックから、最初の Try ステートメントまたは End Try ステートメントに分岐することは可能です。しかし、囲まれた Try…Catch ブロック内への分岐はできません。 これについて、次に示します。

Try キャッチ分岐

構造化例外処理の例

Try...Catch...Finally ステートメントを使った単純なエラー ハンドラーの例を次に示します。

Option Strict On
Imports System.IO

Module Module1
    Private Const FileName As String = "TestFile.data"

    Public Sub Main()

        ' First, create a new data file and write some data to the file.
        ' 1. Create the new, empty data file.
        If File.Exists(FileName) Then
            File.Delete(FileName)
        End If
        Dim fs As New FileStream(FileName, FileMode.CreateNew)

        ' 2. Create a BinaryWriter object for the data.
        Dim writer As New BinaryWriter(fs)

        ' 3. Write some sample data to the file.
        For i = 0 To 10
            writer.Write(i)
        Next i
        writer.Close()
        fs.Close()

        ' Now read from the file you just made.
        ' 1. Create a BinaryReader object for the data stream.
        fs = New FileStream(FileName, FileMode.Open, FileAccess.Read)
        Dim reader As New BinaryReader(fs)

        ' 2. Read data from TestFile.data. The loop terminates with an
        ' EndOfStreamException when an attempt is made to read past
        ' the end of the stream.
        Try
            ' This loop terminates with an EndOfStreamException when it 
            ' reaches the end of the stream.
            While True
                Console.WriteLine(reader.ReadInt32())
            End While
            Console.WriteLine("The data was read with no error.")
        ' 3. Report the first error that is caught, if there is one.
        Catch eosExcep As EndOfStreamException
            ' This Catch block is executed when the reader attempts
            ' to read past the end of the stream.
            Console.WriteLine("End-of-stream exception occurred.")
        Catch IOExcep As System.IO.IOException
            ' For this Catch block, some other error occurred before
            ' the end of stream was reached. Print the standard
            ' exception message.
            Console.WriteLine(IOExcep.Message)
        Finally
            ' The Finally block is always executed.
            Console.WriteLine("Executing the Finally block.")
            reader.Close()
            fs.Close()
        End Try
    End Sub

End Module

Finally ブロックは、前の各 Catch ブロックで行われた動作に関係なく、常に実行されます。 構造化例外処理で Resume または Resume Next を使用することはできません。

注意

前の例では、IOException クラスや EndOfStreamException クラス以外の例外は、処理されずに呼び出し元に戻されます。

参照

処理手順

例外処理のトラブルシューティング (Visual Basic)

参照

Try...Catch...Finally ステートメント (Visual Basic)

BinaryReader

BinaryWriter

FileStream

概念

例外処理の概要 (Visual Basic)

エラーの種類 (Visual Basic)

非構造化例外処理の概要 (Visual Basic)

その他の技術情報

例外処理のタスク (Visual Basic)