例外処理

本ページには広告が含まれています。

プログラムの実行の継続を妨げる異常な事象(エラー)が発生した際に、実行される処理を記述します。

構文
// TRY - FINALLY ルーチン中断時にも必ず実行されます
TRY
処理(EXIT)
FINALLY
処理
ENDTRY
もしくは
// TRY - EXCEPT 実行時エラーが起きた時に実行されます
TRY
処理(エラー)
EXCEPT
処理
ENDTRY
エラーメッセージは特殊変数TRY_ERRMSGに格納
エラー行は特殊変数TRY_ERRLINEに格納
引数
戻り値
TRY_ERRMSG
エラーメッセージ
TRY_ERRLINE
エラー行

TRY節でEXITを記述した場合、FINALLY節は実行されるがEXITEXITを記述した場合は、FINALLY節も実行されずに終了します。

構文エラーと例外

プログラム実行時に発生するエラーには、構文エラー(syntax errorシンタックス エラー例外(exceptionエクセプションの2種類があります。

構文エラーはプログラムの記述ミスがあるときに発生するエラーで、プログラムの実行前に発生します。SyntaxErrorというメッセージと一緒にエラーが発生した行も指摘されるため、プログラムの修正は比較的簡単に行うことができます。

以下に構文エラーが発生する具体的な例を示します。

  • スペルミス
  • 宣言していない変数の使用
  • 関数の引数の数が合わない
  • 変数・定数の二重定義
  • 関数やメソッドの括弧を閉じ忘れている

一方、例外は構文が正しくても発生することのあるエラーです。構文に間違いはないため構文チェックでは検知されず、プログラムの実行中に初めてエラーが出ます。

UWSCのPro版を使っている場合はUWSC Debuggerでデバッグを行い一行ずつ処理を確認することでエラーの原因を見つけることもできますが、エラーが必ず発生するとも限らないため原因を特定することが難しいこともあります。

UWSCではこのようなエラーを適切に処理するために例外の仕組みを備えていて、エラーが発生したとき通常の処理を中断し別の処理を行うことができこれをトラップといいます。

特殊変数

TRY節でエラーが発生したとき特殊変数のTRY_ERRMSGにエラーメッセージ、TRY_ERRLINEにエラー行が代入されます。エラーが発生したときに表示されるメッセージボックスの内容の1行目がエラーメッセージ、2行目がエラー行です。エラー行は行番号だけでなく、その行のプログラムも表示されます。

以下はインプットボックスに入力された数式の計算結果を表示するプログラムです。インプットボックスに入力した3**5という数式が正しくないためEVAL関数 (スクリプト関数)の箇所でエラーが発生してEXCEPT節に処理が飛び、エラーメッセージとエラー行が出力されています。

UWSC
TRY
	PRINT EVAL(INPUT("数式を入力"))
EXCEPT
	PRINT TRY_ERRMSG
	PRINT TRY_ERRLINE
ENDTRY
結果
プレーンテキスト
INPUT:2>3**5
型が合っていない or オーバーフロー
2行目: PRINT EVAL(INPUT("数式を入力"))

正しい数式を入力してエラーが発生しなければEXCEPT節は実行されません。

結果
プレーンテキスト
INPUT:2>3*5
15

TRY_ERRLINEはエラーの発生した行番号とプログラムが代入されるので、行番号のみを数値で取得したい場合は以下のプログラムを実行します。lineに行番号のみが数値で代入されます。

UWSC
TRY
EXCEPT
	DIM line = TRY_ERRLINE
	line = VAL(COPY(line, 1, POS("行目:", line) - 1))
	PRINT line
ENDTRY

トラップ可能なエラー

型が合っていない or オーバーフロー

変数の型が合っていなくて処理ができないときに表示されるメッセージです。数値と文字列で計算をしようとすると表示されます。

KansuCall:Overflow while converting variant of type (xxx) into type (yyy)

日本語訳は「xxx型の変数をyyy型に変換する際にオーバーフローが発生しました」という意味です。大きい数値を扱える型から小さい数値を扱う型に型変換をしたときに表示されるメッセージで、xxxyyyには変数の型が入ります。型が扱える範囲は変数を参考にしてください。
UWSC
DIM a = 32768
a = VARTYPE(a, VAR_SMALLINT)

COM_Error:例外が発生しました。

CREATEOLEOBJ関数 (スクリプト関数)で生成したCOMオブジェクトの処理にエラーが発生したときに表示されるメッセージです。

TRYでの処理の流れ

TRY節でエラーが発生しなかった場合、EXCEPT節は実行されない。

UWSC
TRY
	PRINT 1
EXCEPT
	PRINT 2
ENDTRY

PRINT 3
結果
プレーンテキスト
1
3

FINALLY節はTRY節でエラーが発生しなくても実行される。

UWSC
TRY
	PRINT 1
FINALLY
	PRINT 2
ENDTRY

PRINT 3
結果
プレーンテキスト
1
2
3

TRY節でEXITが実行された場合も、FINALLY節は実行される。

UWSC
TRY
	PRINT 1
	EXIT
FINALLY
	PRINT 2
ENDTRY

PRINT 3
結果
プレーンテキスト
1
2

TRY節でEXITEXITが実行された場合は、FINALLY節は実行されない。

UWSC
TRY
	PRINT 1
	EXITEXIT
FINALLY
	PRINT 2
ENDTRY

PRINT 3
結果
プレーンテキスト
1

TRYの入れ子も可能。

UWSC
TRY
	PRINT 1
	TRY
		PRINT 2
	EXCEPT
		PRINT 3
	ENDTRY
	PRINT 4
EXCEPT
	PRINT 5
ENDTRY

PRINT 6
結果
プレーンテキスト
1
2
4
6

TRY節でエラーが発生した場合それ以降の処理は実行されず、EXCEPT節に飛ぶ。

UWSC
TRY
	PRINT 1
	DIM a = "a"; PRINT 1 / a   // エラー
	TRY
		PRINT 2
	EXCEPT
		PRINT 3
	ENDTRY
	PRINT 4
EXCEPT
	PRINT 5
ENDTRY

PRINT 6
結果
プレーンテキスト
1
5
6

TRYが入れ子でエラーが発生した場合、対応するEXCEPT節に飛ぶ。

UWSC
TRY
	PRINT 1
	TRY
		PRINT 2
		DIM a = “a”; PRINT 1 / a   // エラー
	EXCEPT
		PRINT 3
	ENDTRY
	PRINT 4
EXCEPT
	PRINT 5
ENDTRY

PRINT 6
結果
プレーンテキスト
1
2
3
4
6

EXCEPT節でエラーが発生した場合、ENDTRYの下に飛ぶ。

UWSC
TRY
	PRINT 1
	TRY
		PRINT 2
	EXCEPT
		DIM a = “a”; PRINT 1 / a   // エラー
		PRINT 3
	ENDTRY
	PRINT 4
EXCEPT
	PRINT 5
ENDTRY

PRINT 6
結果
プレーンテキスト
1
2
4
6

エラーの種類

COMオブジェクトによるエラーはCOM_ERR_IGN-COM_ERR_RETを参考にしてください。

関数: (関数名) がありません

存在しないUWSC関数を使用したときに発生します。

以下は「FUKIDASI」とかくべきところを「FUKIDASHI」と書いたためにエラーが発生しています。

UWSC
FUKIDASHI("message")
UWSC
関数: FUKIDASHI がありません
1行目: FUKIDASHI("message")

型が合っていない or オーバーフロー

UWSC
DIM a = "a"
PRINT 1 / a
UWSC
型が合っていない or オーバーフロー
2行目: PRINT 1 / a

IF行のマルチ宣言はNG

IF文のTHEN節にマルチステートメントで複数の命令を書いたときに発生します。

OLE関数が正しく閉じていません

UWSC
IE.Navigate("http://example.com"
)
UWSC
OLE関数が正しく閉じていません
3行目: IE.Navigate("http://example.com"

定数には値を代入できません

CONSTで宣言した定数の値は変更することができません。値が変わることのおる場合は、DIMまたはPUBLICで変数として宣言します。

UWSC
CONST a = 1
a = 2
UWSC
定数には値を代入できません
2行目: a = 2

円周率\(\pi\)や自然対数\(e\)など変更されることのない値は定数として定義します。

UWSC
CONST pi = 3.14159265358
CONST e = 2.718281828459

変数: X が定義されていません

UWSC
DIM a = 1
PRINT a + b
UWSC
変数: B が定義されていません
2行目: PRINT a + b

式がおかしい or 型が合っていない

UWSC
PRINT add(1. 2, 3)
UWSC
式がおかしい or 型が合っていない
1行目: PRINT add(1. 2, 3)

関数名: Resultが無い

FUNCTIONで関数定義をするときはResultで戻り値が必須です。戻り値を返す必要がない場合はPROCEDURE-FENDを使います。

UWSC
FUNCTION add(a, b)
FEND
UWSC
ADD: Resultが無い
2行目: FEND

WHILE に対しWEND が無い

UWSC
WHILE TRUE
	SLEEP(0.001)
UWSC
WHILE に対しWEND が無い
1行目: WHILE TRUE

"IN" もしくは "=" 指定が無い

UWSC
FOR TRUE
	SLEEP(0.001)
NEXT
UWSC
"IN" もしくは "=" 指定が無い
1行目: FOR TRUE

TOが無い

UWSC
FOR i = 1 IN 5
	SLEEP(0.001)
NEXT
UWSC
TOが無い
1行目: FOR I = 1 IN 5

FORに対しNEXTが無い

UWSC
FOR r = 0 TO 9
	FOR c = 0 TO 9
NEXT
UWSC
FORに対しNEXTが無い
1行目: FOR R = 0 TO 9

REPEAT の後に記述はできません

UWSC
REPEAT TRUE
	SLEEP(0.001)
UNTIL
UWSC
REPEAT の後に記述はできません
1行目: REPEAT TRUE

UNTIL に対し REPEAT が無いか式定義がない

UWSC
REPEAT
	SLEEP(0.001)
NEXT
UWSC
UNTIL に対し REPEAT が無いか式定義がない
1行目: REPEAT

対応する FOR が無い

UWSC
	SLEEP(0.001)
NEXT
UWSC
対応する FOR が無い
2行目: NEXT

対応する WHILE が無い

UWSC
	SLEEP(0.001)
WEND
UWSC
対応する WHILE が無い
2行目: WEND

対応する REPEAT が無い

UWSC
	SLEEP(0.001)
UNTIL
UWSC
対応する REPEAT が無い
2行目: UNTIL

NEXT の後に記述はできません

UWSC
FOR i = 0 TO 5
	SLEEP(0.001)
NEXT i
UWSC
NEXT の後に記述はできません
1行目: FOR i = 0 TO 5

ループ外に CONTINUE 文がある

UWSC
IF TRUE THEN CONTINUE
UWSC
ループ外に CONTINUE 文がある
1行目: IF TRUE THEN CONTINUE

ループ外に BREAK 文がある

UWSC
IF TRUE THEN BREAK
UWSC
ループ外に BREAK 文がある
1行目: IF TRUE THEN BREAK

COM_Error

UWSC
TRY
	DIM Excel = CREATEOLEOBJ("Excel.Application")
	Excel.Visible = TRUE
	Excel.Workbooks.Add()
	DIM Worksheet = Excel.Sheets("Sheet10")
EXCEPT
ENDTRY
UWSC
COM_Error:例外が発生しました。
5行目: DIM Worksheet = Excel.Sheets("Sheet10")
Microsoft Visual Basic
実行時エラー '9'
インデックスが有効範囲にありません。

SyntaxError(構文エラー)

関数:(関数名)

定義された構文を間違った書き方をしたときに発生します。

以下はデフォルトパラメータ以降に通常引数を書いたために発生したエラー。

UWSC
PRINT add(1,2, 3, 4)

FUNCTION add(a, b, c = 1, d)
	RESULT = a + b + c + d
FEND
UWSC
SyntaxError
関数:ADD

KansuCall:Overflow while converting variant of type (A) into type (B)

型Aから型Bへの変換時にオーバーフローが発生しました。

UWSC
PRINT VARTYPE(1000, VAR_SBYTE)
UWSC
KansuCall:Overflow while converting variant of type (Double) into type (ShortInt)

KansuCall:Could not convert variant of type (A) into type (B)

型Aから型Bへの変換に失敗したときに発生します。

UWSC
PRINT VARTYPE(NULL, VAR_EMPTY)

Null型からEmpty型への型変換に失敗しました。

UWSC
Could not convert variant of type (Null) into type (Empty)
VAR_EMPTY Empty
VAR_NULL Null
VAR_SMALLINT Smallint
VAR_INTEGER Integer
VAR_SINGLE Single
VAR_DOUBLE Double
VAR_CURRENCY Currency
VAR_DATE Date
VAR_DISPATCH Integer
VAR_ERROR Error
VAR_VARIANT Variant
VAR_UNKNOWN Unknown
VAR_SBYTE ShortInt
VAR_BYTE Byte
VAR_WORD Word
VAR_DWORD LongWord
VAR_INT64 Int64
VAR_ASTR String
VAR_USTR OleStr
VAR_ARRAY
UWSC
CONST xlLastCell = 11

DIM Excel = CREATEOLEOBJ("Excel.Application")
Excel.Visible = TRUE
Excel.Workbooks.Open("D:\Documents\型変換一覧.xlsx")

DIM r = Excel.Range("A1").SpecialCells(xlLastCell).Address    // UString
PRINT r.Row
UWSC
COM_Error:Could not convert variant of type (UnicodeString) into type (Dispatch)

KansuCall:Access violation at address 0040B12A in module 'UDebug.exe'. Read of address xxxxxxxx

'UDebug.exe'がアクセスできない領域にアクセスしようとしたためエラー(アクセス違反)が発生しました。

UWSC
PRINT VARTYPE(100, VAR_DISPATCH)

「xxxxxxxx」の部分には16進数の値が入ります。今回の場合、10進数の100を16進数に変換した「64」。

UWSC
KansuCall:Access violation at address 0040B12A in module 'UDebug.exe'. Read of address 00000064

使い方

Excelでシートの存在確認

以下はエラー発生することを利用した例。Excelでシートを取得できなかった場合エラーが発生するので、シートの存在の有無を確認することができます。

UWSC
TRY
	DIM SheetName ="東京都"
	DIM Worksheet = Excel.Sheets(SheetName)
	PRINT SheetName + "は存在します"
EXCEPT
	PRINT SheetName + "は存在しません"
ENDTRY

異常発生時にもファイルを閉じる

UWSC
TRY
	DIM FID = FOPEN(path)
	エラーが発生する可能性のある処理
EXCEPT
	FCLOSE(FID)
ENDTRY