Visual Basic 6.0 初級講座
VB6対応

 

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

第15回 英単語の練習 前編

 

コントロール編も一応全部終わったので今回と次回の2回では具体的にプログラムを作ってみます。プログラムが完成していく様子を表すために普段私がやっているような段階をふんで行きます。そのためはじめから完成したプログラムの説明をしていくスタイルにはなりません。

作成するプログラムは 英単語練習プログラムです。問題が日本語で出されてその英訳を答えるという形式にします。、また、それなりに使えるプログラムにしようと思っていますので学生の人は活用してみてください。わたしも中学時代に自分で英単語練習プログラムを作って勉強していました。

 

1.まずは簡単に作る

 

まず深く考えないで単純な英単語練習プログラムを作ってみます。日本語を表示するためのラベル(名前はlblJapan)と答えを入力するためのテキストボックス(名前はtxtAnswer)、それに解答するためのコマンドボタン(名前はcmdAnswer)を配置して次のようにすればよいでしょう。

Private Sub Form_Load()

lblJapan.Caption = "基本的な(b)"

End Sub

Private Sub cmdAnswer_Click()

If txtAnswer = "basic" Then 

MsgBox "正解"

Else

MsgBox "はずれ"

End If

End Sub

まずフォームのロードイベントでラベルに「基本的な(b)」と表示させます。そしてコマンドボタン(cmdAnswer)がクリックされたらテキストボックス(txtAnswer)に入力された内容が正解かどうか判断します。正解の時は「正解」、はずれの時は「はずれ」を表示もすることにしましょう。

これで、問題数がたった1問ではありますが英単語練習プログラムは一応完成です。後はこのプログラムを改良していくことにしましょう。

改良すべき点はたくさんあります。たとえば以下の点が気になるでしょう。

・見かけが悪い

・問題数が1問しかない

・キーボードで答えを入力してからマウスでクリックするのは面倒くさい

他にもあるかも知れませんがとりあえずはこれらの点を直していきます。

 

2.拡張対策

 

具体的な改良を始める前にプログラムの構造を変えましょう。このまま改良を加えるとプログラムがごちゃごちゃしてしまいます。一番嫌なのは問題を出す部分がForm_Loadにある点です。これから問題を増やしていくつもりなので、1問解答するごとに次の問題を出題するようにしたいのですがForm_Loadはプログラムを開始した時に1回呼ばれるだけなのでここに出題するためのプログラムを書くのは適切ではありません。

では、どこに書いたらいいでしょうか?私にはどうもふさわしい場所が思いつきません。そこで自分で「問題を出題するためのプロシージャ」を作ることにしましょう。

プロシージャの名前はSetProblemとします。現段階では次のように記述すれば十分でしょう。

Private Sub SetProblem()

lblJapan.Caption = "基本的な(b)"

End Sub

そして、Form_Loadにあった出題のためのコードを削除します。しかしこれだけだといつまで経っても問題が出題されないので最初の1回だけはForm_Loadから出題することにします。そのためには今書いたばかりの「問題を出題するためのプロシージャ」SetProblemを呼び出します。プロシージャを呼び出すにはプロシージャの名前を書くだけで済みますからこの部分は次のようになります。

Private Sub Form_Load()

SetProblem

End Sub

これで下準備は終わりです。ここまでのプログラムの全体を載せておきます。この段階では最初のプログラムと同じ機能しかありません。

Private Sub SetProblem()

lblJapan.Caption = "基本的な(b)"

End Sub

Private Sub Form_Load()

SetProblem

End Sub

Private Sub cmdAnswer_Click()

If txtAnswer = "basic" Then 

MsgBox "正解"

Else

MsgBox "はずれ"

End If

End Sub

 

3.問題数を増やす

 

では、いよいよ問題数を増やしましょう。具体的には1問目の解答が済んだら2問目を出し、それが済んだら3問目を出す。というようにすればよいわけです。ということは「解答が済んだら」というところに着目してcmdAnswer_Clickプロシージャに処理を加えましょう。このプログラムでは解答が済んだらコマンドボタンを押すことになっているので、この場所に解答後の処理を記述するのが適切です。

解答が済んだら「次の問題を出題する」のですが、問題を出題するためにさきほどSetProblemプロシージャを作りましたからこれを呼び出せばよいわけです。

以上の点をふまえるとcmdAnswer_Clickプロシージャは次のように改良されます。

Private Sub cmdAnswer_Click()

If txtAnswer = "basic" Then 

MsgBox "正解"

Else

MsgBox "はずれ"

End If

SetProblem    'ここで次の問題を呼び出している。

End Sub

これで解答するたびにSetProblemプロシージャが呼び出されて次の問題が出題されることになります。

ところで、さっきから「次の問題」と書いていますがまだ問題を作成していません。とりあえず3問くらい作成してみましょう。問題を作成するために専用のLoadProblemプロシージャを作ります。このプロシージャは次のように記述します。

Private Sub LoadProblem()

Question(1) = "基本(b)"

Answer(1) = "basic"

Question(2) = "視覚の"

Answer(2) = "visual"

Question(3) = "番組"

Answer(3) = "program"

End Sub

問題を保存するために変数Question、解答を保存するために変数Answerを作成しました。もちろんこれらの変数の名前は好きにつけてかまいませんができるだけ分かりやすいものにしましょう。

それぞれの変数の後ろに (1) (2) (3) といのがついています。これは直感で分かるように1問目、2問目、3問目を表しています。問題に限らず変数に番号をつけて管理したいと言うことはよくあります。そんなときにはこの例のように変数の後ろに(1)(2)(3)・・・とつけるだけでOKです。

このように番号付きの変数のことを 「配列」 (はいれつ)といいます。

これで問題作成のプロシージャは完成です。これをForm_Loadプロシージャから呼び出せるようにForm_Loadプロシージャの先頭に LoadProblem の一言を追加してください。

次に、「次の問題を出題する」という部分をプログラムします。「次の問題」と言うからには現在何問目なのかを記録しておくのがよいでしょう。このために変数QCountを用意します。SetProblemプロシージャが呼び出されるたびにこの変数の値が1ずつ増えていくようにしましょう。

以上の点を加味すると新しいSetProblemプロシージャは次のようになります。

Private Sub SetProblem()

QCount = QCount + 1

lblJapan.Caption = Question(QCount)

End Sub

問題が変われば答えも変わるので正解を判定するcmdAnswerプロシージャも次のように変更しましょう。

Private Sub cmdAnswer_Click()

If txtAnswer.Text = Answer(QCount) Then

MsgBox "正解"

Else

MsgBox "はずれ"

End If

SetProblem

End Sub

この他に新しくでてきた変数Answer Question QCount を宣言しておくようにします。これらの宣言はフォームの宣言セクションで行うのがよいでしょう。配列であるAnswerとQuestionの宣言はかっこつきで行います。その際に何番目までを使用するかも記述します。ここでは余裕を持って100番目までを宣言しておきましょう。この宣言は次のようになります。 Dim Answer(100) As String 

これで問題が3問ある英単語練習プログラムの完成です。これ以上問題を増やしたければLoadProblemプロシージャにQuestion(4),Answer(4)などを付け加えていけばよいでしょう。

ここまでの全プログラムを下に示しておきます。

Dim Answer(100) As String 
Dim Question(100) As String
Dim QCount As Integer
Private Sub SetProblem()

QCount = QCount + 1

lblJapan.Caption = Question(QCount)

End Sub

Private Sub Form_Load()

LoadProblem    '問題を読み込む

SetProblem        '最初の問題を出題する

End Sub

Private Sub cmdAnswer_Click()

    If txtAnswer.Text = Answer(QCount) Then
        MsgBox "正解"
    Else
        MsgBox "はずれ"
    End If

SetProblem

End Sub

Private Sub LoadProblem()

Question(1) = "基本的な(b)"
Answer(1) = "basic"

Question(2) = "視覚の"
Answer(2) = "visual"

Question(3) = "番組"
Answer(3) = "program"

End Sub

 

4.見かけをよくする

 

見かけをよくするのは簡単です。ラベルやテキストボックスのBackColorプロパティやFontプロパティをお好みに合わせて変えてください。

たとえば、問題を表示するラベルはもっと字を大きくしたいのでFontプロパティをプロパティウィンドウから選択してサイズを大きめにしましょう。

とにかくこのあたりは自分でいろいろやってみて下さい。プロパティウィンドウからプロパティをいろいろ変更しているとそれなりに見かけがよい物ができるでしょう。

 

5.使いやすくする

 

とりあえず完成したとはいう物のなかなか使いにくいプログラムになりました。どこが使いにくいか思いつくままに列挙してみましょう。

・答える前にテキストボックスの内容をいちいち消去するのは面倒くさい。

・答えるたびにコマンドボタンをクリックするのは面倒くさい。

・答えるたびにメッセージボックスがでてくるのはわずらわしい。

「面倒くさい」「わずらわしい」というたぐいの物は我慢さえすればちゃんと機能しているという意味にもとれます。しかし、使い勝手の悪いプログラムを私は許せません。みなさんもパソコンを使っていて操作法がわかりにくいプログラムがあったり、やりたいことがパッとできないプログラムがあったりいろいろいらいらしたことがあるのではないですか?そういったプログラムを撲滅するためにも自分で作るプログラムくらいはせめて自分で納得できる使い勝手の良さを実装しましょう。

さて、上記の不満を一つずつつぶしていきます。

@答える前にテキストボックスの内容をいちいち消去するのは面倒くさい。

これは解答するたびにテキストボックスの内容を消去するようにプログラムすればOKです。具体的にはcmdAnswer_Clickプロシージャに次の1行をつけ加えることになります。


txtAnswer.Text = ""
 

また、プログラムをスタートさせたときに最初 text1 と表示されているのも嫌なのでこれはプロパティウィンドウでtxtAnswerのTextプロパティを空白にしておくことで回避しましょう。

A答えるたびにコマンドボタンをクリックするのは面倒くさい。

実はTabキーを押してからEnterキーを押せばマウスにさわることなくコマンドボタンをクリックできます。しかしもっとやりやすいように改良しましょう。Enterキーを押すだけでOKというのが使いやすいでしょう。

Enterキーが押されたかどうかはForm_KeyPressプロシージャで判定します。そのためにまずフォームのKeyPreviewプロパティをTrueにしてください。

そしてForm_KeyPressプロシージャに次のようにプログラムします。

Private Sub Form_KeyPress(KeyAscii As Integer)

If KeyAscii = vbKeyReturn Then cmdAnswer_Click

End Sub

Form_KeyPressプロシージャはキーボードのキーが押された場合に呼び出されます。どのキーが押されたかはKeyAsciiという変数を調べれば分かります。KeyAsciiには押されたキーによって異なった数値が自動的に格納されています。この数値を 文字コード といいます。

Enterキーの場合は文字コードは13ですが、組み込み定数である vbKeyReturn と記述して代用することもできます。

Enterキーが押された場合にはコマンドボタンをクリックするのと同じ効果を出したいのでプログラムからコマンドボタンのクリックイベントを呼び出します。イベントプロシージャを呼び出すにはそのプロシージャの名前を記述するだけでOKです。この場合はcmdAnswer_Clickとします。

B答えるたびにメッセージボックスがでてくるのはわずらわしい。

メッセージボックスを表示しないようにすればよいのですがその場合はメッセージボックス以外に正解か不正解かを表示する方法を考えなければなりません。

今回はグラフィックメソッドを利用して○×を表示することにします。

メッセージボックスで「正解」と表示する代わりに次のコードを加えてください。

Circle (ScaleWidth \ 2 , ScaleHeight \ 2) , ScaleHeight \ 2 , RGB(255,0,0) 

このコードはフォームに赤い円を書く物です。フォームの中心に円が描かれるように簡単に座標も計算しています。SacleWidth ScaleHeight はそれぞれフォームの横幅と縦幅を意味していて \ はわり算の記号です。この記号は小数点以下は計算してくれないのですがその分計算速度が速くなります(といってもこのくらいのプログラムでは早さは関係ない)。

なお、もしフォームの大きさで たて の方が長い場合には 最後の ScaleHeight \ 2 を ScaleWidth \ 2に変えてください。

不正解の場合には次のコードで×を書くことにします。

Line ( 0 , 0 ) - (ScaleWidth , ScaleHeight) , RGB(0,0,255)

Line ( 0 , ScaleHeight) - (ScaleWidth , 0) , RGB(0,0,255)

○の場合にも×の場合の線が細くて嫌なのでフォームのDrawWidthプロパティを10にしましょう。このプロパティはグラフィックメソッドで描画される線の太さを表しています。

さて、以上の点をふまえると完成するプログラムの全体は次のようになります。

Dim Answer(100) As String 
Dim Question(100) As String
Dim QCount As Integer
Private Sub SetProblem()

QCount = QCount + 1

lblJapan.Caption = Question(QCount)

End Sub

Private Sub Form_Load()

LoadProblem    '問題を読み込む

SetProblem        '最初の問題を出題する

End Sub

Private Sub Form_KeyPress(KeyAscii As Integer)

If KeyAscii = vbKeyReturn Then cmdAnswer_Click

End Sub

Private Sub cmdAnswer_Click()

Cls        '前に書いた○や×を消す

If txtAnswer.Text = Answer(QCount) Then

Circle (ScaleWidth \ 2 , ScaleHeight \ 2) , ScaleHeight \ 2 , RGB(255,0,0)

Else

Line ( 0 , 0 ) - (ScaleWidth , ScaleHeight) , RGB(0,0,255)

Line ( 0 , ScaleHeight) - (ScaleWidth , 0) , RGB(0,0,255)

End If

txtAnswer.Text = ""

SetProblem

End Sub

Private Sub LoadProblem()

Question(1) = "基本(b)"

Answer(1) = "basic"

Question(2) = "視覚の"

Answer(2) = "visual"

Question(3) = "番組"

Answer(3) = "program"

End Sub

 

6.不満

 

これでずいぶん使い勝手が良くなりました。問題も自分で増やしていけばかなり多くできます。でも不満もまだまだあります。たとえば「いつも同じ順番で問題がでてくる」というのはどうですか。やはりランダムに出題してほしい物です。

それから問題を作成するのが面倒くさい。面倒くさいと言ってもどうしようもない気がしますが改良する方法はあります。

これらの点は次回に改良することにしましょう。また次回は完成版英単語練習プログラムをダウンロードできるようにするつもりです。

最後に1つ今言っておきますと ○ や × が表示されるときにテキストボックスやコマンドボタンの部分では○×が欠けて見えます。これはしょうがないとしてもせめてラベルの部分では欠けてほしくない物です。この問題を解決するにはラベル(lblJapan)のBackStyleプロパティを 0−透明 にするだけです。

それではまた次回。