VBAのクイズの作り方とは?考え方やチュートリアルも解説!


VBAでクイズを作る具体的な方法がわからない・・・
VBAでクイズを作るためのチュートリアルはないだろうか・・・
できれば、作り方だけでなく作るときの考え方も知りたいな・・・

VBAで簡単なマクロを作ったことがあっても、クイズアプリのようにランダムで問題を出すようなマクロの作り方がわからない人もいるのではないでしょうか。エクセルは一覧データを使って処理を作りやすいため、VBAはクイズを作りやすい言語です。ただ、何から調べていけばいいかわからない人が多いと思います。

こんにちは!フリーランスエンジニア兼テックライターの脇坂です。

この記事では、VBAでクイズアプリを作りたいと思っている方向けに、VBAでクイズアプリを作るときの考え方・具体的な作り方を解説します。

この記事はこんな人のために書きました。

  • これからVBAでクイズを作ろうと思っている人
  • クイズの作り方だけでなく考え方も知りたい人

目次

VBAでクイズを作るときに必要な考え方

最初に、VBAでクイズを作るときの考え方について解説します。

クイズは、以下の流れで作ります。


1. 問題一覧をまとめたシートを作る
2. 問題の表示・解答画面を作る
3. 問題を問題一覧シートからランダム表示する処理を作る
4. 解答ボタンをクリックしたときの処理を作る

大きく分けると、事前準備(問題一覧シート・画面) → コーディング(表示処理・解答ボタンクリック処理)の流れですね。このままだと良くわからないと思うので、それぞれ詳しく解説しますね。

【チュートリアル】VBAのクイズアプリの作り方

問題一覧シートの作成

まず、問題一覧シートを作成します。

最初に前提ですが、今回は1つの質問に対して複数の選択肢から回答するクイズアプリを作ります。そのため、問題一覧シートには質問、選択肢1 ~ 3、正解Noの列を以下のように用意しました。


問題一覧シート

例えば、選択肢1の答えが正解だった場合は、正解Noが1になるようにデータを作っています。選択肢の答えを判断しやすいように、正解Noを作っているのです。

問題一覧シートができたら、問題解答画面を作ります。具体的な作り方について次で解説しますね。

問題解答画面の作成

次に、問題解答画面を作っていきます。

画面を作るときは、ユーザーフォームを使います。ユーザーフォームを使えば、次のように画面を作ることができるのです。


ユーザーフォームで作った画面

ここからは、ユーザーフォームを使って画面を作る方法を解説していきます。一度もユーザーフォームを使ったことがない方は、先に以下を見ておくことがおすすめです!

まっさらな画面を用意する

まず、挿入→ユーザーフォームを選択して、空の画面を用意します。

ユーザーフォームの挿入方法


作成直後のユーザーフォーム

右側に表示されたツールボックスを使えば、テキスト、ボタン、ラベルなどを追加して画面を作っていくことができます。次に、質問エリアを作る方法を解説しますね。

質問エリアの作り方

まず、質問エリアの作り方を解説します。具体的には、以下の部分です。


質問エリア

1. 「■質問」ラベルを用意する
まず、ラベルを選択して、画面にラベルを追加します。


ラベルの追加

2. ラベルの表示名(Caption)を変更する
次に、プロパティウィンドウを表示して、ラベルの表示名(Caption)を変更します。


Captinoの変更

今回は、「■質問」にCaptionを変えています。

3. 質問表示用のテキストボックスを用意する
次に、テキストボックスを選択して、質問表示用の背景を追加します。


質問表示用の背景追加

4. テキストボックスを入力不可に変更
テキストボックスは、そのままだと入力ができてしまうため、入力不可に設定を変更します。プロパティのEnabledをFalseに変更します。


テキストボックスを入力不可に変更

5. 問題を表示するためのラベルを用意する
次に、ラベルを選択し、テキストボックスの背景に重なるように、問題を表示するラベルを追加します。
※ラベルの追加方法は、割愛


問題表示用のラベル追加

ここまでで、質問エリアの作成が完了です。次に、回答エリアを作っていきます。

回答エリアの作り方

次に、回答エリアの作り方を解説します。具体的には、以下の部分です。


回答エリア

1. 「■回答」ラベルを用意する
「■質問」のときと同じ方法で、「■回答」ラベルを用意します。
※質問エリアと同じ方法なので、説明割愛


回答ラベルの追加

2. 回答エリアの背景白エリアを用意
質問エリアと回答エリアの見た目を統一するために、回答エリアにも入力不可のテキストボックスを用意します。
※質問エリアと同じ方法なので、説明割愛


回答表示用の背景追加

3. 回答を選択するためのオプションボタンを追加
次に、質門の解答を選択するための、オプションボタンを追加します。


オプションボタン追加方法

追加後の画面:

オプションボタン追加後の画面

ただ、オプションボタンの背景色がグレーになっているため、見栄えが良くないですよね。そのため、次のように背景色を白に変更します。

4. オプションボタンの背景色を白(強調表示された文字列)に変更

オプションボタンの背景色変更

変更後の画面:

オプションボタンの背景色変更後

これで、背景色が違和感なくなりましたね。同じ流れで、オプションボタンを3つ増やします。

オプションボタン追加後の画面:

オプションボタン追加後

ここまでで、回答エリアの作成が完了です。次に、ボタンエリアを作っていきます。

ボタンエリアの作成

次に、ボタンエリアの作り方を解説します。具体的には、以下の部分です。


ボタンエリア

1. 「回答する」ボタンの作成
まず、コマンドボタンを選択し、ボタンを作ります。


コマンドボタンの追加方法

2. ボタンの表示名を変更する
次に、オプションから表示名(Caption)を変更します。


ボタンの表示名変更

同じように、「質問を変える」ボタンも作りましょう。

ボタン追加後の画面:

質問を変えるボタン追加後

ここまでで、ボタンエリアの作成が完了です。次に、全体の見た目を整えていきます。

全体の見た目を整える

「実行 → Sub/ユーザーフォームの実行」または「F5キー」を押して、一度画面を実行してみましょう。

実行後の画面:

実行後の画面

文字が小さく、画面の要素の位置も整っていないですよね。そのため、見た目を整えましょう。

具体的には、以下の流れで整えるのがおすすめです。

  • 文字サイズの変更
  • 表示間隔の変更

文字サイズの変更方法

文字サイズは、プロパティのFontにある「…」ボタンをクリックすると、変更できます。


Fontの変更方法

変更するときは、統一感を持たせるために、以下のようにルールを決めることがおすすめです。


■ルールの例

  • 全体文字:14px
  • ボタン文字:22px

ルールをもとに変更すると、次のようになりました。


Font変更後

表示位置を変更する方法

文字を大きくしたことによって、ボタンの文字が見えなくなったり、全体的に窮屈になっていますよね。そのため、サイズを変更して見た目を微調整しましょう。

ユーザーフォームにはドットがついているので、ドットの間隔を統一すると見やすくなります。


見た目を変更するときのコツ

全体の上下以外にもボタンの上下の間隔、ボタン同士の間隔などを意識して統一するだけで、使い勝手が良くなります。

TabIndexを変更して順番を整理する

ユーザーフォームは、画面を実行したときにTabキーを押して選択する順番をプロパティに持っています。そのため、画面の要素が正しくTabキーで移動するように、TabIndexを次のように変更しましょう。

TabIndexの変更例:

TabIndexの変更例

変更方法:

TabIndexの変更方法

コントロールにオブジェクト名を付ける

ここまでできたら、VBAを書くための準備に入ります。

VBAでは、オブジェクト名を指定して、各コントロール(テキストボックス、オプションボタン、コマンドボタン)などを操作します。そのため、わかりやすい名前にオブジェクト名を変更しておくことが重要です。

今回は以下のように変更しました。

  • 質問:Label2 → lblQuestion
  • 選択肢1:OptionButton1 → opbAnser1
  • 選択肢2:OptionButton2 → opbAnser2
  • 選択肢3:OptionButton3 → opbAnser3
  • 回答するボタン:CommandButton1 → btnAnserAction
  • 質問を変えるボタン::CommandButton2 → btnChangeQuestion

ラベル、オプションボタン、ボタンを判断できるように、lbl、opb、btnを名前の先頭3文字に入れています。以降の文字は、オブジェクト名を見るだけで何のコントロールかわかるように、名前を付けています。

VBAで処理を書くときに、オブジェクト名だけ見れば何を設定しているのかわかるようにしておくことが重要です。

問題表示処理の作成

次に、問題を表示する処理を作ります。

ユーザーフォームでは、UserForm_Initializeで画面を起動するときの処理を作ることができます。そのため、UserForm_Initializeの中で質問、選択肢1 ~ 3を表示する処理を作っていきます。

UserForm_Initializeのコード

Private Sub UserForm_Initialize()
    '問題一覧シートから、ランダムで値取得
    Call QuizCreate
End Sub

QuizCreateのコード:

Sub QuizCreate()
    '①クイズを指定するため30までのランダム数字を取得
    Dim quizNo  As Integer  'クイズ画面に出すクイズ番号
    Const quizNum = 5 'クイズの総数
    quizNo = Int(5 * Rnd + 1)
    
    '②ランダム数字を使って、クイズ情報を取得
    Dim intQuestionRow As Integer
    intQuestionRow = quizNo + 1 '1行目がヘッダのため1プラス
    With Worksheets("問題一覧")
        pubStrQuestion = .Cells(intQuestionRow, 2).Value
        pubStrAnser1 = .Cells(intQuestionRow, 3).Value
        pubStrAnser2 = .Cells(intQuestionRow, 4).Value
        pubStrAnser3 = .Cells(intQuestionRow, 5).Value
        pubIntAnserNo = .Cells(intQuestionRow, 6).Value
    End With
    
    '③ユーザーフォームに初期値設定
    lblQuestion = pubStrQuestion
    opbAnser1.Caption = pubStrAnser1
    opbAnser1.Value = False
    opbAnser2.Caption = pubStrAnser2
    opbAnser2.Value = False
    opbAnser3.Caption = pubStrAnser3
    opbAnser3.Value = False

End Sub

グローバル変数用の標準モジュール:

'クイズアプリに使うグローバル変数
Public pubStrQuestion As String   '質問
Public pubStrAnser1 As String     '選択肢1
Public pubStrAnser2 As String     '選択肢2
Public pubStrAnser3 As String     '選択肢3
Public pubIntAnserNo As String   '正解No

①の処理で、問題一覧シートから問題を取得する行数をランダムで計算しています。Rnd関数を使って計算したランダム値に、データの総数(5行)をかけて、ヘッダ行分の1を追加した行数を計算しています。

次に、①で計算した行の問題一覧のデータを、グローバル変数の質問、選択肢1 ~ 3、正解Noに値を入れています。グローバル変数に入れている理由は、回答するボタンを押したときに質問、回答の情報を残しておくためです。

このように、処理をまたいで値を保持したいときは、グローバル変数用の標準モジュールを別で作っておくことがおすすめです。

最後に、③でユーザーフォームの質問、選択肢1~3に値を入れています。選択肢1~3はオプションボタンなので、表示したときは選択されていないようValueにFalseもいれています。

これで、表示処理は完了です。

ちなみに、UserForm_InitializeからQuizCreateの処理を実行している理由は、質問を変えるボタンの処理を作るときに、QuizCreateを実行するだけで済むようにするためです。このように、同じ処理になる箇所は1つにまとめて使いまわしできるようにしておくことがおすすめです。

別のSubを実行するCallの使い方がわからない方は、以下を見るのがおすすめです!

回答ボタンクリック処理の作成

次に、回答ボタンをクリックする処理を作っていきます。

1. ユーザーフォームでボタンダブルクリックで処理を作る
まず、ボタンをダブルクリックして、クリック処理を作ります。

ダブルクリックすると、「オブジェクト名_Click」のマクロが自動で作られるため、その中に以下の処理を書いていきます。

回答するボタンクリック処理:

Private Sub btnAnserAction_Click()
    '①クリックした番号を取得
    Dim selectOptionNo As Integer
    If opbAnser1.Value = True Then
       selectOptionNo = 1
    ElseIf opbAnser2.Value = True Then
       selectOptionNo = 2
    ElseIf opbAnser3.Value = True Then
       selectOptionNo = 3
    Else
       MsgBox "回答を選択してください。", vbExclamation
       Exit Sub
    End If
    
    '②回答結果に応じて、メッセージ変更
    If pubIntAnserNo = selectOptionNo Then
        MsgBox "正解です!おめでとうございますー!"
        Exit Sub
    Else
        MsgBox "不正解です。" & pubIntAnserNo & "番名の選択肢が正解です。", vbCritical
        Exit Sub
    End If
    
End Sub

①では、selectOptionNoの変数に、クリックしたオプションボタンの番号をセットしています。何も選択していなかった場合を考慮し、else文にMsgBoxで「回答を選択してください。」のメッセージと共に、処理を終了するExit Subを入れています。

②では、①でセットした番号と、画面を表示するときにセットしたグローバル変数の正解Noの値を比較し、正否判定をしています。一致している場合は正解、不一致の場合は不正解でメッセージ表示する処理ですね。

このように、簡単にクイズを作ることができました。

質問を変えるボタンクリック処理の作成

ただ、問題を1度表示して回答するだけでは、クイズとして成り立っていないですよね。そのため、最後にクイズを変更する処理を作りましょう。

画面初期化するUserForm_Initializeで既に作っていた、QuizCreateの処理をクリック時に実行すればOKです。具体的には、以下のようになります。

btnChangeQuestionクリック時の処理:

Private Sub btnChangeQuestion_Click()
    Call QuizCreate
End Sub

これで、クイズアプリの完成です。

クイズアプリの機能を増やすためにおすすめの知識

ここまででクイズアプリは作れるのですが、クイズの結果を保存しておきたいという方もいますよね。

その場合は、結果を別シートに書き込む処理を追加すればOKです。セルに値を書き込む処理については、以下で詳しく解説しています。

興味がある方は、以下を参考に作ってみてくださいね!

まとめ

今回は、VBAでクイズアプリを作る方法について解説しました。

ユーザーフォームを初めて使う人は、わからないことも多かったかもしれません。ただ、一度画面を使ったアプリを作っておけば、次からは楽に作ることができます。

1から徹底的にまとめているので、ぜひ実際に手を動かして作ってみてくださいね!

この記事を書いた人

北海道出身の30歳で、フリーランスエンジニア兼テックライターとして活動中。新卒入社したメーカー系のIT企業で、システムエンジニアとして約5年勤務。

Webアプリ、業務アプリ開発において、要件定義 ~ 運用保守まで様々な経験あり。また3歳の娘がいる1児のパパで、日々娘との時間を確保するために仕事を頑張っています!
侍エンジニアでは、【誰でもわかるレベルのわかりやすさ】を意識して、記事を執筆中。

目次