連載:VB 6ユーザーのための
これならマスターできるVB 2005超入門

第4回 トラブルは水際で防げ〜入力時のチェックとエラー処理

羽山 博
2006/11/22
Page1 Page2 Page3 Page4

■桁数チェックだけでいいの?

 ここまでで、入力チェックの基本の基本は終わり。あとは、考え得る限り不正なデータを漏らさず捕らえるだけだ。そう考えると、商品コードの桁数しか見ないというのはずいぶんとずさんなチェックだ。形式さえ合っていれば中身はどんなものであってもパス……ではさすがに困る。

 例えば、商品コードは数字だけでできていて、英字やそのほかの記号が使われないということがあらかじめ分かっていれば、文字種のチェックも含めるべきだろう。数字だけでできていることを確認したいのであれば、Integer型に用意されているParseメソッドを利用するとよい。Parseメソッドは文字列を数値に変換するメソッドで、文字列の中に数字以外の文字が入っているとエラーになるからだ。

 Integer型の範囲は−2,147,483,648から+2,147,483,647なので、8桁の数字であれば必ず整数化できる。Parseメソッドは、オーバーフローの場合や引数の文字列がNothingだった場合にもエラーとなるが、桁数チェックでそれらのエラーが起こらないことは保証されているので、エラーとなるのは数字以外の文字が入っている場合だけだ。

 VB 6でのエラー処理では、On Errorステートメントしか使えなかったが、VB 2005では、Try〜Catch〜Finallyステートメントを使った構造化例外処理ができるようになっている*2

*2 ここまでは、直感的に分かりやすいという理由で「エラー」「エラー処理」という言葉を使ってきたが、より包括的で正確な用語としては「例外」「例外処理」の方がふさわしい。

 On Errorステートメントは、おせじにも使いやすいとはいいにくいもので、GIGOと同じくらい使い古された「スパゲティ・プログラム」という言葉で表される、ごちゃごちゃとしたコードの元凶となっている。

■構造化例外処理を使おう

 では、VB 2005の新機能である構造化例外処理の方法を見ていこう。構造化例外処理のために使うTry〜Catch〜Finallyステートメントは以下のような形式になっている。

Try

  例外が起こる可能性のあるステートメント

Catch 変数名 As 例外の型

  例外が起こったときに実行するステートメント

Finally

  最後に実行するステートメント

End Try

 これに、先ほど触れたInteger.Parseメソッドを当てはめてみると、次のようになるだろう。ここでは、整数化した結果は特に使わないので、Parseメソッドの結果を変数に代入しなくてもよい。また、最後に実行するステートメントは特にないので、Finally部分は省略していいだろう。

Try

  Integer.Parse(txtCode.Text)

Catch ex As Exception

  e.Cancel = True
  lblAlert.Text = "数字以外の文字が含まれています"
  txtCode.Select(0, txtCode.TextLength)

End Try

 Tryとは「試みる」「挑戦する」、Catchとは「受け取る」といった意味なので、「何かやってみて、おかしなことが起こったら、それを受け取って対処する」という感じがよく伝わってくる。

 ちなみに、ラグビーではゴールすることを「トライ」というが、かつてはトライしても点が入らず、ゴールキックの挑戦権を得るだけだったのでそう呼ばれているらしい。冒頭にオール・ブラックスの話を出したのは、この話をしたかったから……というわけではないが。

 では、このコードを、すでに書いたイベント・ハンドラに組み込んでみよう。実際に、コード・エディタの画面で「Try」と入力して[Enter]キーを押すと、「IntelliSenseコード・スニペット」と呼ばれる機能が働き、「Catch」や「End Try」が自動的に挿入される(図7)。


図7 IntelliSenseコード・スニペットの機能を使って入力を省力化
「Try」と入力して[Enter]キーを押した時点で「End Try」までの構文が自動的に挿入される。「TryC」と入力して[Tab]キーを押してもよい。“TryCF[Tab]”ならFinally部分も含んだ構文が挿入される。ほかにも、“If[Tab]”で「If〜End If」を挿入、“Select[Tab]”で「Select Case〜End Select」を挿入、“For[Tab]”で「For〜Next」を挿入など、数々のショートカットが用意されている。

 以下が完成したコード。lblAlert.Textをクリアしておくコードを最初に持ってきた。また、ActiveControlプロパティがtxtCodeである場合には何もしない(ActiveControlプロパティがtxtCode以外のときだけフォーカスの移動をキャンセルする)というのは共通なので、最初にチェックすることとした。

' 商品コード・テキストボックスのValidatingイベント・ハンドラ
Private Sub lengthCheck(ByVal sender As System.Object, ByVal e As System.ComponentModel.CancelEventArgs) Handles txtCode.Validating
  lblAlert.Text = ""
  If ActiveControl Is txtCode Then
    Exit Sub
  End If
  If txtCode.TextLength <> 8 Then
    e.Cancel = True
    lblAlert.Text = "商品コードは8桁です"
    txtCode.Select(0, txtCode.TextLength)
  Else
    Try
      Integer.Parse(txtCode.Text)
    Catch ex As Exception
      e.Cancel = True
      lblAlert.Text = "数字以外の文字が含まれています"
      txtCode.Select(0, txtCode.TextLength)
    End Try
  End If
End Sub
完成したValidatingイベント・ハンドラ
8桁入力されている場合には、さらに数字以外の文字が含まれていないかチェックする。水色の文字の所が構造化例外処理のTry〜Catch〜Finallyステートメント。これまでのコードに素直に組み込んでみた。

 念のため、ここで実行例を示しておこう。商品コードが8桁でない場合は、これまでと同じメッセージが表示されるが、商品コードが8桁であっても、数字以外の文字が含まれていると、図8のような表示となる。


図8 数字以外の文字が含まれている場合もエラーとする
英字ばかりを入力した場合はもちろん、数字と英字が混在している場合もエラーとなる。また、桁数が8桁でない場合はこれまでのエラーが表示される。


 INDEX
  連載:VB 6ユーザーのためのこれならマスターできるVB 2005超入門
  第4回 トラブルは水際で防げ〜入力時のチェックとエラー処理
    1.サンプル・プログラム4 − データベース検索のためのダイアログ
    2.Validatingイベントを使って入力チェック
  3.構造化例外処理を使おう
    4.統一感のある構造化例外処理とFinallyの落とし穴
 
インデックス・ページヘ  「これならマスターできるVB 2005超入門」


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メールマガジン 新着情報やスタッフのコラムがメールで届きます(無料)
- PR -

注目のテーマ

業務アプリInsider 記事ランキング

本日 月間
ソリューションFLASH