Visual Basic 2019 入門
20.算数ドリルを作ろう その5
今回は [ 算数ドリルを作ろう その4 ] の続きです。
説明の中でよく分からない所がでてきたら、とりあえずプログラムを入力して実行結果を確認してみましょう。
そして説明が難しく思えたら、そのまま先に進むのも一つの手です。
分からない所でずっと止まっているのも苦痛ですから。
でも、ときどき前のページに戻って読み返すのも効果的ですよ。
問題作成のサブルーチンを作ろう
必要なユーザーインターフェース部分はできたので、これからは内部処理です。
まずは問題の作成をしましょう。
問題は何度も出題することになるので専用のサブルーチンを作ります。
前準備として、問題を呼び出すための Form1_Load を用意しましょう。
フォームの何もないところでダブルクリックすると、自動で作られます。
Form1_Load はこのフォームが作られるとき1度だけ実行されます。
問題を出題するサブルーチン MondaiSakusei を作ります。
とりあえず計算タイプは足し算で作ります。
問題の作成には乱数を使います。
1桁の計算なので、 rand.Next(1, 10) を使い1から9を発生させます。
乱数を忘れてしまったときは次を参照してください。
[ ハイ&ローゲームを作ろう その7 ]
サブルーチン MondaiSakusei が正しく作動するか確認するため Form1_Load の中で呼び出します。
それでは実行してみましょう。
ちゃんと問題が表示されました。
問題を表示している部分の(21 行目)
MondaiLbl.Text = noA & " + " & noB & " = "
ここの + と = の左右には、スペースを入れてます。
これは単純に見た目を良くするためにしていることです。
答え合わせのサブルーチンを作ろう
次は答え合わせです。
サブルーチン Kotaeawase を作りました。
何度もくり返す処理をサブルーチンにする使い方が一般的ですが、いくつかの処理を1つにまとめることで、プログラムを見やすくするという使い方もあります。
変数 noC を作り、ここに計算の答えを入れておきます。
この変数と入力値を比較することで、答え合わせができる訳です。
AppendText には vbCrLf(改行コード)を必要に応じて含ませるようにします。
改行コードがなければ続けて表示されます。
改行したいところに入れましょう。
○ は「まる」を、× は「ばつ」を漢字変換したものです。
InBox_KeyPress の中に、答え合わせと出題のサブルーチンを追加しました。
これで( 出題 → 入力 → 答え合わせ → 出題 )というループになります。
(1回目の出題は Form1_Load で行われます)
テストとして出力していたものはコメントにします。(10 行目)
実行してみましょう。
エラー音を消そう
ところで・・・
答えを入力するたび「ポン」と鳴ってますよね。
このエラー音(ビープ音)が不快なので、鳴らないようにします。
入力エラーについて
問題の作成と答え合わせができたので、メインとなる処理はできました。
と言いたい所ですが、まだまだなんです。
実行して、答えに文字を入力してみて下さい。
文字を入力すると見慣れないメッセージが表示されます。
「 バンドルされていない例外 」
これは簡単に言ってしまえばエラーが発生したのです。
処理の中に、間違った手順があることを示しています。
以前にもエラーの話はしましたが、それはビルド中に発生するエラーでした。
今回は実行中に発生したエラーなので、対応が変わります。
エラーに関する情報は、だいたい次のところを見るといいでしょう。
エラーの状況をしっかりと把握してから対応を考えます。
不具合がありそうな所を IDE が教えてくれます。
(よく分からない場合もあります)
呼び出し履歴を見ると、入力処理 InBox_KeyPress の中から呼ばれた
答え合わせ Kotaeawase で止まったことが分かります。
これらの情報から次の行
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 キーが押されると答え合わせの処理が呼ばれますが
入力データが「 何も無い 」状態で変数 noC と比較するとエラーになります。
ちなみに、何もない状態を Null(ヌル)といいます。
これを回避するために、入力データが Null の場合は除外するように
プログラムを変更します。
And InBox.Text <> ""
これで Null を除外します。
”(ダブルコーテーション)を2つ続けて書くと、Null になります。
文字列用の変数を初期化するときにも使えます。(17 行目で使ってますね)
実行してみて下さい。
空打ち(なにも入力せず Enter を押す)してもエラーになりません。