連載

プロフェッショナルVB.NETプログラミング
―― VB 6プログラマーのためのVB.NET入門 ――

第16回 例外処理を極める

(株)ピーデー
川俣 晶
2002/09/07

Page1 Page2 Page3

例外の自作

 VB 6(Visual Basic 6.0)では、Error文やErr.Raiseメソッドを用いてエラーを意図的に発生させることができる。このとき、あえてエラーが定義されていない番号を指定することができる。これは自作プログラム内で発生する各種独自エラーを、VB 6のエラー処理メカニズムを利用して処理するために使用される。これをうまく使えば、プログラムをきれいにまとめられる可能性がある。以下に、独自エラーを、VB 6のエラー処理機能を用いて処理した例を示す。

  1: Private Sub checkLicense()
  2:   If Dir("c:\user\license.txt") = "" Then
  3:     Err.Raise 1234
  4:   End If
  5: End Sub
  6:
  7: Private Sub Form_Load()
  8:   On Error GoTo licenseErrorHandler
  9:   checkLicense
 10:   Exit Sub
 11:
 12: licenseErrorHandler:
 13:   If Err.Number <> 1234 Then
 14:     Err.Raise Err.Number
 15:   Else
 16:     MsgBox "ライセンスファイルがありません。使用するためにはライセンス認証が必要です。"
 17:     End
 18:   End If
 19: End Sub
VB 6のエラー処理機能を用いて独自のエラーを処理しているサンプル・プログラム1

 これを実行すると以下のようになる。

サンプル・プログラム1の実行結果

 このソース・コードは、3行目のErr.Raiseメソッドによって独自エラーを発生させている。このソースでは、適当に与えた1234という番号によって、独自エラーを識別するようにしている。このエラーは、13行目のIf文による判断され、1234番以外は通常のエラー処理に移行し、1234番ならメッセージを出力して終了する。

 では、これと同等のソース・コードがVB.NET(Visual Basic .NET)でも記述できるだろうか? 以下は記述してみた例である。

  1: Private Sub checkLicense()
  2:   If Dir("c:\user\license.txt") = "" Then
  3:     Err.Raise(1234)
  4:   End If
  5: End Sub
  6:
  7: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
  8:   On Error GoTo licenseErrorHandler
  9:   checkLicense()
 10:   Exit Sub
 11:
 12: licenseErrorHandler:
 13:   If Err.Number <> 1234 Then
 14:     On Error GoTo 0
 15:   Else
 16:     MsgBox("ライセンスファイルがありません。使用するためにはライセンス認証が必要です。")
 17:     End
 18:   End If
 19: End Sub
サンプル・プログラム1と同等な処理を記述したVB.NETのサンプル・プログラム2

 これを実行すると以下のようになる。

サンプル・プログラム2の実行結果

 見てのとおり、ほとんど変わりないものが記述できる。しかし、VB.NETの場合、構造化例外処理を用いて処理するという選択もある。もし、構造化例外処理を使うとすれば、どのように記述できるだろうか? 実際に記述してみたのが以下の例である。

  1: Class LicenseErrorException
  2:   Inherits Exception
  3:   Public Sub New(ByVal msg As String)
  4:     MyBase.New(msg)
  5:   End Sub
  6: End Class
  7:
  8: Private Sub checkLicense()
  9:   If Dir("c:\user\license.txt") = "" Then
 10:     Throw New LicenseErrorException("ライセンスファイルがありません。")
 11:   End If
 12: End Sub
 13:
 14: Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
 15:   Try
 16:     checkLicense()
 17:   Catch ex As LicenseErrorException
 18:     MsgBox(ex.Message & "使用するためにはライセンス認証が必要です。")
 19:     End
 20:   End Try
 21: End Sub
サンプル・プログラム2を、構造化例外処理を用いて記述したVB.NETのサンプル・プログラム3

 これを実行すると以下のようになる。

サンプル・プログラム3の実行結果

 このソースのポイントは、1〜6行目で定義されたクラスである。このクラスは、Exception(System.Exception)クラスを継承した例外クラスである。これらのクラスはシステムが提供するDivideByZeroExceptionなどと同じように例外機能で使用することができる。実際に、10行目のThrow文で例外を発生させ、17行目のCatch文でそれをキャッチしている。もう1点、このソースでは、例外を投げる際に引数に理由を示す文字列を記述している点が機能的に異なっている。このサンプル・ソースには、「ライセンスファイルがありません」という状況しか存在しないが、ライセンスファイルが正しくなかったり、期限が切れていたりする場合にも、それなりのメッセージを表示させたい場合は、このような引数が有効である。もちろん、それぞれの理由ごとに、例外クラスを作成して区別するという方法もある。

 さて、念のため、細かい部分を説明しておこう。2行目のInherits文はExceptionクラスを継承したクラスであることを示している。3〜5行目はコンストラクタである。4行目のMyBaseは、スーパークラスのコンストラクタを呼び出すために使用される。つまり、4行目では、引数を親クラスのコンストラクタに引き渡しているわけである。Exceptionクラスにはメッセージを受け取って保持する機能があるので、メッセージの保存はそれに任せている。


 INDEX
  連載 プロフェッショナルVB.NETプログラミング
  第16回 例外処理を極める
  1.例外の自作
    2.InnerExceptionについて
    3.Finally文の確実性
 
「プロフェッショナルVB.NETプログラミング」


Insider.NET フォーラム 新着記事
  • 第2回 簡潔なコーディングのために (2017/7/26)
     ラムダ式で記述できるメンバの増加、throw式、out変数、タプルなど、C# 7には以前よりもコードを簡潔に記述できるような機能が導入されている
  • 第1回 Visual Studio Codeデバッグの基礎知識 (2017/7/21)
     Node.jsプログラムをデバッグしながら、Visual Studio Codeに統合されているデバッグ機能の基本の「キ」をマスターしよう
  • 第1回 明瞭なコーディングのために (2017/7/19)
     C# 7で追加された新機能の中から、「数値リテラル構文の改善」と「ローカル関数」を紹介する。これらは分かりやすいコードを記述するのに使える
  • Presentation Translator (2017/7/18)
     Presentation TranslatorはPowerPoint用のアドイン。プレゼンテーション時の字幕の付加や、多言語での質疑応答、スライドの翻訳を行える
@ITメールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)

注目のテーマ

Insider.NET 記事ランキング

本日 月間