Visual Basic 6.0 初級講座
VB6対応

 

Visual Basic 中学校 > VB6 初級講座 >

第22回 エラー処理

 

今回は「エラー」について取り上げます。エラーにどう対処したらよいのか。予期しないエラーに対してどのような対策を講じればよいかを説明します。

 

1.エラーとは

 

エラーとはプログラマーなら誰もが経験したことがあるでしょう「まちがい」のことです。ただ、「まちがい」といってもいろいろありますから、「エラー」にもいろいろあります。

まず、スペルミス(字を間違った)によるエラーがあげられます。たとえば、Dim X と書くべきところを、Din X と書いてしまってそのまま気づかずにプログラムを実行したとしましょう。どうなるでしょうか?

多分「Sub または Function が定義されていません」と表示されるのではないでしょうか?場合によっては他のメッセージが出現する事もありますがエラーはエラーです。この手のスペルミスによるエラーは結構多いと思いますが優秀なVBがいちいち「どこがちがう」みたいに間違っている場所を指摘してくれますのでそれほど困りません。(ただし、VBのチェックを潜り抜けるスペルミスは非常に厄介(やっかい)です。これについては後述します(後で書きます))。

スペルミスのほかにはどんなエラーがあるでしょうか?いくつかあげてみましょう。

X = CDate("ヤッホー")

この例は「型が一致しません。」というエラーが出るでしょう。

Circle(120 , 240 , 360) , 500

この例はVBのチェックに引っかかりますがあえて実行すると「構文エラー」が発生します。

Public Const X = "ABCDEFG"

この例をフォーム上に記述するとエラーになります。(フォームではPublic Constは使えないのです)。

きりがないのでこのくらいにしておきます。

結局「エラーとは○○のことです。」というような説明はしませんでしたがエラーがどんなものかはわかってもらえたと思います。また、こういったエラーのほかにも「論理エラー」と呼ばれるちょっと変わったものや俗に「不正な処理」と呼ばれる恐ろしいエラーもあります。

 

2.エラーが発生するとどうなるか

 

エラーが発生すると処理がとまってエラーメッセージが表示されます。これは非常にまずいことです。というのはそのプログラムを使っている人はエラーが発生すると作業が中断され、場合によっては作業中のデータが全く失われる危険にさらされるし、そのプログラム自体が「エラー」つまり「まちがい」のあるいいかげんなプログラムと思われてしまうからです。

さて、エラーが発生して処理がともった後はどうなるでしょうか。もし、そのプログラムをVB上で実行しているならばエラーメッセージとともに「終了」「デバッグ」「ヘルプ」などの選択肢が表示されてプログラムを修正したり、そのままプログラムを終了して見直したりできます。とりわけ、「デバッグ」はプログラムを中断状態にしたまま作業ができるので、作業中のデータがいきなり消えてしまうということはありません(ただ、VB上で実行しているプログラムでこった作業をする人というのはあまりいないでしょう)。

しかし、プログラムが(コンパイルされて)単独で実行されている場合は、エラーメッセージを閉じると、プログラムは強制終了させられてしまいます。これがどんなにまずいことかは言うまでもありません。

 

3.エラー対策の基本

 

エラー対策の基本はこの強制終了をふせぐことにあるのではないでしょうか?万一エラーが発生してしまってプログラムが続けられなくなってもせめてユーザー(プログラムを使っている人)に作業中のデータを保存させるくらいのことは考えるとかそういう発想です。

また、エラーが発生しても小さなエラー(たとえば、効果音を鳴らそうとしたらそのWavファイルが存在していなかった)などはプログラムを終了させる必要はほとんどありません。その場合にも何もエラー対策をしていないと強制終了させられてしまいます。こういった場合は「プログラムを続行させる」というのが望ましい解決法でしょう。

 

4.エラー処理 入門編

 

今回は前置きがずいぶん長くなりました。なんだか難しそうだと感じられた方もいらっしゃるかもしれませんが実は基本は簡単です。もっとも簡単なエラー処理は「エラーを無視する」ことです。こうすればエラーが発生しても強制終了はしません。エラーを無視させるには次のような1行を入力するだけです。

VB6 対応 VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応


On Error Resume Next
 

このたったの1行で「エラーがあっても次を続けなさい」という意味になるのです。少し実験してみましょう。コマンドボタンを配置して次のようにプログラムしてみてください。

VB6 対応

Private Sub Command1_Click()

Dim X As Long

X = "あいうえお"

MsgBox X

End Sub

このコードにはエラーがあります。どこだかわかりますか?入門者には少し難しいかもしれませんがこの説明を読んでいる皆さんにはわかるでしょう。エラーが発生するのは X = "あいうえお" の部分です。XはLong型、つまり整数として宣言されているのに文字を代入しようとしているのでエラーになるのです。エラーになるとわかっていても今回のテーマがエラーなので実行してみてください。たしかに「型が一致しません」というエラーが発生しましたね。「デバッグ」ボタンを押すと X = "あいうえお" の部分が黄色く表示されるでしょう。優秀なVBは「この行で 型が一致していない処理が行われています」と教えてくれているのです。

では、このコードを改造して次のようにしてみてください。

VB6 対応

Private Sub Command1_Click()

Dim X As Long

On Error Resume Next

X = "あいうえお"

MsgBox X

End Sub

実行してみるとどうですか?みごとにエラーが無視されたでしょう。0 と表示されるのは X = "あいうえお" がエラーで無視されて、その後Xには何も代入されていないのでXの値が初期値0のままで表示されたからです。このOn Error Resume Next を知っているだけでずいぶんと違うものです。

ちなみに、On Error Resume Next の前にエラーがあった場合はもちろんひっかかってエラーになります。それで通常On Error Resume Nextを使う場合はプロシージャの先頭で使います。

 

5.エラー処理 初級編

 

On Error Resume Nextも便利なのですが問題があります。エラーは「無視すれば良い訳ではない」という点です。無視するだけですむなら最初からエラーなんてないはずです。たとえば次のコードを打ち込んでみてください。

VB6 対応

Private Sub Command1_Click()

Dim FileName As String

Dim FileSize As Long

On Error Resume Next

FileName = "C:\Windows\gdi64.dll"

FileSize = FileLen(FileName)

MsgBox FileName & "のサイズは" & FileSize & "バイトです。"

End Sub

FileLen関数 (読み方:FileLen = ファイルレン)は初めて出てきましたが、これはファイルのサイズをバイト数で返す関数です。意外と便利な技もあったりして隠れた名関数です。

さて、このプログラムを実行すると C:\Windows\gdi64.dllのサイズは0バイトです。 と表示されるのではありませんか?ファイルのサイズが0バイトということは確かにありえます。でもこの場合はこの情報はまちがいです。On Error Resume Nextをはずして実行してみればわかりますが、実は FileSize = FileLen(FileName) でエラーが発生しています。VBの出すエラーメッセージは「ファイルがみつかりません。」です(環境によっては「パスがみつかりません。」と表示されます)。そうです、C:\Windows\gdi64.dllなどというファイルは存在しないのです。にもかかわらず、On Error Resume Nextがついているとこのエラーが無視されて次の行に処理が移るので、その結果あたかもサイズ0のファイルC:\Windows\gdi64.dllが存在するかのようなメッセージが表示されてしまうのです。

これはまずですね。まさにエラーは無視すればよいわけではないということです。では、無視する以外にどんな解決法があるでしょうか。ここで提案するのは次のようなコードです。

VB6 対応

Private Sub Command1_Click()

Dim FileName As String

Dim FileSize As Long

On Error Goto ErrorTrap

FileName = "C:\Windows\gdi64.dll"

FileSize = FileLen(FileName)

MsgBox FileName & "のサイズは" & FileSize & "バイトです。"

ErrorTrap:

End Sub

On Error Resume NextではなくOn Error Goto を使います。On Error Gotoはエラーが発生した場合にそのエラーを無視するのではなく 〜 で指定された部分にジャンプします。ためしにやってもらえばわかりますがこのコードを実行すると何も表示されません。それは表示を命令しているMsgBoxの前にエラーが発生して、処理が ErrorTrap: に飛ばされるからです。

このOn Error Goto を知っていればほとんどのエラーに対応できるでしょう。

ところで、このOn Error Goto は使いなれてくると次のような使い方をしたくなります。

VB6 対応

'これは良くない例です。

Private Sub Command1_Click()

Dim FileName As String

Dim FileSize As Long

On Error Goto ErrorTrap

FileName = "C:\Windows\gdi64.dll"

FileSize = FileLen(FileName)

MsgBox FileName & "のサイズは" & FileSize & "バイトです。"

ErrorTrap:

MsgBox "エラーが発生しました。"

End Sub

つまり、エラーが発生した場合は独自のエラーメッセージを表示させようとするものです。しかし、このプログラムには問題があります。それはエラーが発生しなかった場合にも"エラーが発生しました。"と表示されてしまう点です。この点を回避するために一般的には次のようにプログラムします。

VB6 対応

Private Sub Command1_Click()

Dim FileName As String

Dim FileSize As Long

On Error Goto ErrorTrap

FileName = "C:\Windows\gdi64.dll"

FileSize = FileLen(FileName)

MsgBox FileName & "のサイズは" & FileSize & "バイトです。"

Exit Sub        'エラーが発生しなければここで終了

ErrorTrap:

MsgBox "エラーが発生しました。"

End Sub

 

6.Errオブジェクト

 

さらに進んだエラー処理について解説しましょう。VBにはエラー処理を円滑(えんかつ)に行うためにErrという名前のオブジェクトが備わっています。このオブジェクトはエラーが発生すると自動的にそのエラーの情報を取得してくれるので大変便利に使えます。

たとえば、次のようにすると発生したエラーの番号とエラーメッセージを取得することができます。

VB6 対応 VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応

MsgBox Err.Number

MsgBox Err.Description

ただ、エラーがないときにこのコードを実行してもあまり意味がないのでわざとエラーの出るコードを書いて実験してみましょう。

VB6 対応

Private Sub Command1_Click()

Dim Count As Long

On Error Resume Next

Count = "ABCDE"

If Err.Number <> 0 Then

MsgBox "発生したエラーの番号は " & Err.Number

MsgBox "エラーメッセージは " & Err.Description

End If

End Sub

実行してみると13番のエラー「型が一致しません」が発生していることがわかります。また、エラーが発生していないときはErr.Numberは0なので、この例のように If Err.Number <> 0 Then とすると、エラーが発生したときは という条件を表すことになります。この方法は On Error Resume Nextと合わせて使うと特に有効です。なぜなら、On Error Resume Next だけではエラーが発生したのかしていないのかわからないからです。

なお、ErrオブジェクトはNumberプロパティが既定のプロパティなので .Number を省略して If Err <> 0 Then と書くことができます。さらに、If節の中では 0 以外の数は True として扱われるのでこの形をさらに縮めて If Err Then と書くことができます。この書き方は「もし、エラーなら」のようにうまく読むことができるため一部のプログラマが好んで使うようです。覚えておくと良いでしょう。

余談かもしれませんが、ErrオブジェクトにはRaiseという面白いメソッドがあります。このメソッドは「エラーを発生させる」という機能を持ちます。たとえば、

VB6 対応 VB.NET 2002 対応 VB.NET 2003 対応 VB2005 対応


Err.Raise 7
 

とすると 7番のエラーが発生します。この機能はオブジェクトを自作する場合などに使う機会があります。

 

7.その他の手法

 

エラー処理にはまだいくつかの手法があります。代表的なものを紹介して今回の講義を終了したいと思います。

On Error Goto 0

このステートメントはOn Erorrを無効にします。

Resume Next

エラーが発生した次の行から実行を再開します。たとえば、次のように使います。

VB6 対応

Private Sub Command1_Click()

On Error Goto ErrTrap

Chdir "R:\"        'Rドライブがない環境ではここでエラーが発生

MsgBox "終わります。"

Exit Sub

ErrTrap:

If Err = 76 Then Resume Next    '発生したエラーが76番の場合は無視して続行

End Sub

Resume

Resume Nextとほとんど同じですが、エラーが発生した次の行から実行を再開するのではなく〜で指定された行から再開する点が異なります。〜の部分には ErrTrap: のように行ラベルを指定します。

Error関数

この関数はエラー番号を引数にとって、エラーメッセージを返します。

たとえば次のようなことが可能です。

MsgBox Error (17)

この関数とリストボックスを利用して100番までのエラーメッセージをすべて表示させるなどのことができます。その例は次のようになります。

VB6 対応

Private Sub Command1_Click()

Dim K As Long

For K = 1 To 100

List1.AddItem Error(K)

Next K

End Sub

 

8.最後に

 

以上で今回は終了です。エラー処理は裏方の作業で地味なのですが結構重要です。今回紹介した手法を用いればほとんどのエラーに対応できるでしょうから今までのプログラムを見直して問題がありそうな個所にはなんらかのエラー処理を付け加えてみたらいかがでしょうか。