VisualBasic 2015 入門
20.算数ドリルを作ろう その5
今回は [ 算数ドリルを作ろう その4 ] の続きです。
説明の中でよく分からない所がでてきたら、とりあえずプログラムを入力して
実行結果を確認してみましょう。
そして説明が難しく思えたら、そのまま先に進むのも一つの手です。
分からない所でずっと止まっているのも苦痛ですから。
でも、ときどき前のページに戻って読み返すのも効果的ですよ。
問題作成のサブルーチンを作ろう
必要なユーザーインターフェース部分はできたので、これからは内部処理を作ります。
まずは問題の作成からです。
問題は何度も出題することになるので、サブルーチン MondaiSakusei とします。
計算タイプは足し算にします。
問題の作成には乱数を使います。
1桁の計算なので、 rand.Next(1, 10) を使い1から9を発生させます。
乱数を忘れてしまったときは次を参照してください。
[ ハイ&ローゲームを作ろう その7 ]
サブルーチン MondaiSakusei が正しく作動するか確認するため
Form1_Load の中で呼び出しています。
それでは実行してみましょう。
ちゃんと問題が表示されました。
問題を表示している部分の
MondaiLbl.Text = noA & " + " & nob & " = "
ここの + と = の左右には、スペースを入れてます。
これは単純に見た目を良くするためにしていることです。
答え合わせのサブルーチンを作ろう
次は答え合わせです。
こちらもサブルーチンとして作ります。
何度もくり返す処理をサブルーチンとする使い方が一般的ですが
いくつかの処理を1つのサブルーチンにまとめることで、プログラムを
見やすくするという使い方もあります。
変数 noC を作り、ここに答えを格納します。
この変数と入力値を比較することで、答え合わせができる訳です。
AppendTextにはvbCrLf(改行コード)を必要に応じて含ませるようにします。
そうすることでプログラム上は複数箇所で処理をしても、表示するとき1行になります。
入力処理 InBox_KeyPress の中に、答え合わせと出題のサブルーチンを追加しました。
これで( 出題 → 入力 → 答え合わせ → 出題 )というループになります。
実行してみましょう。
入力エラーについて
問題の作成と答え合わせができたので、メインとなる処理はできました。
と言いたい所ですが、まだまだなんです。
実行して、答えに文字を入力してみて下さい。
文字を入力すると見慣れないメッセージが表示されます。
「….. 例外が ….. 発生しました」
これは簡単に言ってしまえばエラーが発生したのです。
処理の中に、間違った手順があることを示しています。
ここで原因を調べるため中断をクリックして、IDE を確認します。
不具合がありそうな所を IDE が教えてくれます。(よく分からない場合もあります)
呼び出し履歴を見ると、入力処理 InBox_KeyPress の中から呼ばれた
答え合わせ Kotaeawase で止まったことが分かります。
コード編集ウィンドウでは、異常がありそうな所に色を付けてくれます。
出力ウィンドウに表示されたメッセージでエラーの内容が分かります。
「追加情報:String "gp" から型 ‘Double’ への変換は無効です」
これらの情報から次の行で
If noC = Inbox.Text Then
数値と文字列を比較したので例外が発生したことが分かります。
ちょっと難しい話ですが、数値と文字列を比較してはいけないんです。
さて、原因が特定できたので停止ボタンをクリックしてデバッグ状態を停止します。
デバッグ状態とは、処理の状況やエラーの原因を探るためのものです。
少しずつ使い方を覚えていきましょう。
入力エラーを無視する?
数値だけを入力して欲しいのに、文字を入力されてエラーになってしまう、
この状況をどうしますか?
ネットで他の VB 入門サイトを調べてみると、ときどきエラーを無視する方法を
教えている所があります。
試しにやってみましょう。
On Error Resume Next
この行を答え合わせの所に追加します。
実行してみると、処理は中断することなく続けられます。
しかし結果をみると、文字を入力した所はすべて正解になっています。
エラーを無視する方法は簡単にできますが、正しく使おうとすると
かなり高いスキルが必要になります。
今回の場合であれば、エラーの内容を調べ、数値以外の入力ならばこれを無視して再び入力状態にする、という仕組みを作らないといけなくなります。
さらに注意することがあります。
それは、どんなエラーも無視されてしまうことです。
今回のプログラムはシンプルなので、処理の異常に気が付きやすいです。
ですが、これが複雑なプログラムだったら
エラーが発生していても、なかなか間違いに気が付かないということもありえます。
原因を見つけるのもかなり難しくなります。
エラーを無視する方法は、プログラムの仕組みをしっかりと覚えた上で
使うようにしましょう。
数値のみ入力可能にする
さて、エラーを無視できないのであれば、どうすればいいのでしょうか?
この場合はエラーを出さないようにするのです。
つまり、数値のみ入力を受け付けるようにします。
先ほどテストした On Error Resume Next はもう使わないので
削除しましょう。
新しく追加した行は、むずかしいのでそのまま覚えてもかまいません。
数値のみ受け付けたいときに、この処理を追加すればいいのです。
一応、簡単に説明すると
文字コード0よりも小さく、9よりも大きく、さらに、バックスペース以外の時は
入力されたものを無効にしています。
e.KeyChar < "0"c Or e.KeyChar > "9"c
この部分だけ文字コード表で見てみると次の範囲になります。
And e.KeyChar <> vbBack
これはバックスペース以外のときを条件に追加しています。
e.Handled = True
これはいま入力されたことを無効にする処理です。
実行してみましょう。
まずは数値が入力できるか確認します。
そして入力した数値をバックスペースで消せることも確認しましょう。
次は文字の入力です。
プログラムが正常に動いているなら、文字の入力はできなくなっています。
Null(ヌル)のデータ
数値のみ受け付けるようになって、これで完成と思ったことでしょう。
まだダメなんです。
実行して数値を入力せず、そのまま Enter キーを押してみてください。
エラーが発生しますね。
基本的に Enter キーの情報は、入力を決定するためのものなので
無視することはできません。
Enter キーが押されると、答え合わせの処理が呼ばれますが
このとき入力データが何も無い、このような状態を Null(ヌル)といいますが
これと変数 noC の比較をしてもエラーとなるのです。
これを回避するために、入力データが Null の場合は除外するように
プログラムを変更します。
And InBox.Text <> ""
これで Null を除外します。
”(ダブルコーテーション)を2つ続けて書くと、Null になります。
文字列用の変数を初期化するときにも使えます。
実行してみて下さい。
空打ち(なにも入力せず Enter を押す)してもエラーになりません。