エラー番号とメッセージの管理: Err ステートメントと Error ステートメント

Err ステートメント

Err ステートメントはエラー番号を設定します。Err ステートメントは、カレントエラー番号を返す Err 関数に対応します。

構文は次のとおりです。

Err = errNumber

エラー番号は、エラー発生時に LotusScript® によって自動的に設定するか、スクリプト内のこのステートメントによって明示的に設定できます。エラー番号が設定されると、LotusScript は常に自動的に Error 関数の値をそのエラー番号に関連付けられたエラーメッセージに設定します。エラー番号がゼロに設定されると、Error 関数の値は初期値の空の文字列 ("") にリセットされます。

Err ステートメントは、Error ステートメントのようにエラーを発生させることはありません。エラー番号 (と Error 関数の値) をリセットするだけです。したがって、カレントエラーがない間は、エラー番号 Err はゼロ以外です。

Error ステートメント

Error ステートメントはエラーを発生させ、オプションとしてそのエラーに関連付けるエラーメッセージを指定します。

構文は次のとおりです。

Error errNumber [ , msgExpr ]

オプションの msgExpr 文字列をステートメントに含めなければ、このステートメントはスクリプトを実行するときにエラーを発生させます。errNumber がすでに定義されているエラー番号であれば、このステートメントの効果は、スクリプトの実行時にエラーが発生した場合と同じです。例えば、LotusScript はエラー番号 11 でゼロによる除算エラーを定義したとします。この場合、次のステートメントは、ゼロによる除算を行うステートメントを実行して実際にエラーが発生したときと同じ効果があります。

Error = 11

Error ステートメントに msgExpr を含めると、エラーが発生したときに報告されるエラーメッセージを指定することになり、そのエラーに対するエラー処理は無効になります。

エラーの処理: On Error ステートメント

実行時に認識されるすべてのエラーには、エラーを識別するそれぞれのエラー番号が付きます。認識されているエラーがスクリプトの実行中に発生すると、LotusScript はエラー番号を記録した後、その番号を参照する On Error ステートメントの指示に従って処理します。

例えば、次の On Error ステートメントのどちらかを作成すれば、エラー番号 357 が発生したときにどのように対応するかを LotusScript に通知できます。

On Error 357 GoTo apoc600
On Error 357 Resume Next

事前に定義されているエラーを On Error ステートメントで参照するときは、エラー番号の代わりにエラー用に定義されている定数を使用できます。

例として、lserr.lss の中の一般的なエラー用のエラー番号と定数を定義する 2 つのステートメントを次に示します。

Public Const ErrDivisionByZero      = 11 
' Division by zero
Public Const ErrIllegalFunctionCall = 5 
' Illegal function call

これで、On Error ステートメントで番号 11 と 5 を記述する必要がなくなります。次のような形式でステートメントを作成すれば、スクリプトが読みやすくなります。

On Error ErrDivisionByZero ...
On Error ErrIllegalFunctionCall ...

独自のエラー番号に定数を定義できます(独自のエラー番号は 1000 ~ 1999 の範囲内で定義する必要があります)。そうすれば、エラーを参照する Error ステートメントと On Error ステートメントで、番号の代わりに定数名を使用できます。

以下に例を示します。

Const ooBounds = 677              
' A specific out-of-bounds error
' ...
Error ooBounds
' ...
On Error ooBounds ...

On Error Goto label を使用する

カレントエラーに対して最後に実行された On Error ステートメントの書式が On Error GoTo label の場合、LotusScript はそのラベルの付いているステートメントから実行を続けます。ステートメントは、そのエラーのエラー処理ルーチンを開始します。エラー処理ルーチンのステートメントの数はいくつでも構いませんが、ラベルの位置で実行されるステートメントで開始し、実行時に検出される次の Resume、Exit Sub、Exit Function、Exit Property、または End ステートメントまで続きます。エラーはこれらのステートメントのどれかが実行されるときに処理されるとみなされます。

On Error ステートメントにエラー処理ルーチンが開始する位置のラベルを指定する場合は、そのラベルの付いたステートメントが On Error ステートメントと同じプロシージャ内になければなりません。これは、GoTo ステートメントがプロシージャの外にあるラベル付きステートメントには、制御を渡すことができないからです。コンパイラはラベル付きステートメントが同一プロシージャ内にあることを調べ、同一プロシージャ内にない場合はコンパイルエラーを生成します。

プロシージャ外のエラー処理ルーチン

LotusScript では、エラーが発生したプロシージャ内のエラー、またはカレントプロシージャを呼び出したプロシージャ内のエラーを処理できます。カレントプロシージャがエラーを処理しない場合、LotusScript は呼び出し元プロシージャに制御を戻し、そこでエラー処理ルーチンを探します。呼び出し元のプロシージャがエラーを処理しない場合は、呼び出し元の呼び出し元、さらにその呼び出し元という形で検索が続けられます。この方法で適切なエラー処理ルーチンが見つからない場合は、実行が終了し、そのエラー用のエラーメッセージが生成されます。

以下に例を示します。

' The sub TestHand generates a division-by-zero error.
' Since TestHand doesn't specify how to handle the error,
' control returns to the calling procedure SuperHand when
' the error occurs. SuperHand contains an error-handling
' routine for division by zero. Control passes to that
' routine, which prints a message and exits from SuperHand.
Sub TestHand 
   Dim num As Single 
   num! = 1
   Print num! / 0
End Sub
Sub SuperHand
   On Error GoTo DivZero 
   Call TestHand()
   Exit Sub
DivZero:
   Print "Continuing after calling sub TestHand."
   Exit Sub
End Sub
Call SuperHand()
' Output:
' Continuing after calling sub TestHand.

On Error ステートメントの特殊な書式を使用して、指定されたエラーは特定の処理を受信しないことを明示的に示すことができます。

構文は次のとおりです。

On Error errNumber GoTo 0

この場合、errNumber という番号のエラーは、通常のエラー処理プロシージャで処理されることを示しています。

次の例は、サブルーチン TestHand が以下のように変更された場合に、前の例の結果は変わらないことを示します。

Sub TestHand 
   Dim num As Single
   On Error ErrDivisionByZero GoTo 0 
   num! = 1
   Print num! / 0
End Sub

カレントプロシージャではエラーは処理されないことを指定するには、次の書式のステートメントも使用できます。このステートメントは、プロシージャではエラーは何も処理されないことを明示的に示すので、エラー処理ロジックがより明快になります。

On Error GoTo 0

他の On Error ステートメントと同様、特定のエラーに別の処理を指定する On Error ステートメントをこの後に指定すれば、このステートメントのエラーに対する影響を上書きできます。

例えば、次の一対の On Error ステートメントは、ゼロによる除算エラーがラベル DivZero にあるエラー処理ルーチンにより処理され、その他のエラーはこのプロシージャ内では処理されないことを指定します (他のエラー用のエラー処理ルーチンは、プロシージャの呼び出し元で検索されます)。

On Error GoTo 0 
On Error ErrDivisionByZero GoTo DivZero

特殊な書式の On Error ステートメントである On Error GoTo 0 は、ステートメントが参照するエラーのいずれも処理しません。参照するエラーはどれも現在のプロシージャでは処理されない ということを明示的に示しています。そのようなエラーが発生した場合、LotusScript は、エラーの処理方法を指定する On Error ステートメントがないかどうか、呼び出し元プロシージャの連鎖を上方に向かって検索します。

エラー処理ルーチンを終了する

エラー処理ルーチンを終了させるステートメントが Resume ステートメントの場合、Err、Erl、Error の値は初期値にリセットされます。それぞれの初期値は、ゼロ、ゼロ、空の文字列 ("") です。ステートメントが Exit Sub、Exit Function、または Exit Property の場合は、値はリセットされません。

エラー処理ルーチン内のエラー

エラー処理ルーチンの実行中にエラーが発生した場合は、そのエラーがカレントエラーになります。実行は終了し、関連付けられているエラーメッセージが表示されます。

例 1

次の例は、スクリプト内でどのようにランタイムエラーが発生するかということと、スクリプトを変更してエラーを回避または処理する方法を示します。ここで示されている分かりやすいエラー処理では、On Error と Resume ステートメントが使用されています。通常、エラー処理にはこの 2 つをよく使用します。

次のスクリプトには、ユーザーが指定した名前のファイルの 1 行目からいくつかの値を取り出す GetLine という名前のサブルーチンが含まれています。以下に例を示します。

Sub GetLine
   Dim number1 As Integer, number2 As Integer, number3 _
     As Integer
   Dim fileName As String
   ' Prompt the user to enter a file name, and assign the
   ' result.
   fileName$ = InputBox$("Enter a file name: ")
   Open fileName$ For Input As #1      ' This is line 6.
   Input #1, number1%, number2%, number3%
   Print number1%, number2%, number3%    
   ' Print the input values.
   Close #1
End Sub

サブルーチン GetLine が実行されると、InputBox$ 関数によるプロンプトに対して存在しないファイルの名前をユーザーが入力した場合は、Open ステートメントでエラーが発生します。このスクリプトにはエラーを処理するステートメントが含まれていないため、このスクリプトの実行は終了し、エラーメッセージが出力されます。

Call GetLine()
' Output:
' Fail: RunTime Error 101 Unable to open file at Line 6

例 2

次の例では、上記のスクリプトが変更されて、ファイルを開く際にエラーが発生したときにエラーを処理する On Error ステートメントが含まれています。Open ステートメントが失敗した場合、スクリプトを終了してエラーメッセージを出力する代わりに、エラーを識別する情報が出力され、ユーザーに新しいファイル名を入力するように要求します。

Sub GetLine
   Dim number1 As Integer, number2 As Integer, number3 _
    As Integer
   Dim fileName As String
   ' Designate an error-handling routine to handle an error.
   On Error GoTo NoExist
GetName:
   fileName$ = InputBox$("Enter a file name: ")
   Open fileName$ For Input As #1    ' This is line 8.
   Input #1, number1%, number2%, number3%
   Print number1%, number2%, number3%
   Close #1
   ' Done. Exit from the sub GetLine. (Don't continue on
   ' to the error-handling routine at the label NoExist.)
   Exit Sub
NoExist:
   ' Come here when any error occurs.
   ' Print the values of built-in functions that give
   ' information about the error: an error message,
   ' the error number, and the line number in the script
   ' where the error occurred.
   Print Error(), Err(), Erl()
   ' Resume execution at the label GetName.
   Resume GetName
End Sub
Call GetLine()
' The user twice enters a file name that doesn't exist,
' and then a valid file name. The values read in from
' the file are 11, 22, and 0. 
' Output:
' Unable to open file         101           8 
' Unable to open file         101           8
' 11            22            0