4択問題のプログラムで「次の問題」に移行する処理で困っています

このQ&Aのポイント
  • 「次の問題」ボタンをクリックするとデータテーブルに格納された問題、選択肢が表示され順次解答をしていくのですが、現在の「次の問題」ボタンのプログラムではデータテーブルの「解答」と「正解」に1つずれが生じてしまいます。
  • 下記は「次の問題」ボタンのプログラムです。
  • 4日ぐらい四苦八苦しているのですが、このバグを解消する方法を知りたいです。お願いします。
回答を見る
  • ベストアンサー

4択問題のプログラムで「次の問題」に移行する処理で困っています

現在私は画像のような4択の問題のを解答し最後に何問正解していたかを表示するプログラムを作成しています。 データテーブルに「問題(Question)」「選択肢(Answer1~4)」「解答(SelectAnswr)」「正解(CorrectAnswer」「正解の解説(Explanation)*今質問中では使用させません」を格納しています。 画像はプログラムを立ち上げた直後のものです。 「次の問題」ボタンをクリックするとデータテーブルに格納された問題、選択肢が表示され順次解答をしていくのですが今現在の「次の問題」ボタンのプログラムではデータテーブルの「解答」と「正解」に1つずれが生じてしまいます。 「解答」に一番最初に格納されているのが毎回「ア」になってしまいます。 下記に「次の問題」ボタンのプログラムを示します。 Private Sub NextQuestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextQuestion.Click '選択肢を選択可能にする GroupBox1.Enabled = True Question.Text = DataSet1.DataTable1(i).Question Answer1.Text = DataSet1.DataTable1(i).Answer1 Answer2.Text = DataSet1.DataTable1(i).Answer2 Answer3.Text = DataSet1.DataTable1(i).Answer3 Answer4.Text = DataSet1.DataTable1(i).Answer4 '正誤確認 If Answer1.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ア" ElseIf Answer2.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "イ" ElseIf Answer3.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ウ" ElseIf Answer4.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "エ" End If If DataSet1.DataTable1(i).SelectAnswer = DataSet1.DataTable1(i).CorrectAnswer Then total = total + 1 End If i = i + 1 '終了 If 10 = i Then MsgBox("あなたの正解数は10門中" & total & "問です!") Me.Close() End If Answer1.Checked = True End Sub *変数iはPublicで宣言しています。 このバグを解消するのに4日ぐらい四苦八苦しているのですが限界が近いです。 知恵をかしてください。おねがいします。

質問者が選んだベストアンサー

  • ベストアンサー
回答No.2

回答開始を「次の問題」ボタンで共用しているため、最初の問題が出た瞬間に正誤判定が行われてしまいます。しかも i がインクリメントされているために、第1問は強制的に「回答無し」となり、この歯車がずれたまま進んでいますね。 そもそも、変数 i の役割があやふやです。i は「現在の問題」なのか「次の問題」なのか。配列の添え字に使う変数を「i」にしていることが、コーディングの混乱を招いているように思えます。intCurrent等、変数の役割は明確にしたほうがよいでしょう。設計に慣れていないうちは特に。 また、「次の問題」ボタンは「回答開始」のクリックと「次に進む」クリックで、役割が異なるため処理を分けなければいけません。 ・回答開始の時は「問題の表示」をするだけで正誤判定してはいけません。 ・次の問題へ移る時は、先に「正誤判定」を行い、i を進めて「問題の表示」を行わなければなりません。 この異なる処理をひとつのメソッドで行おうとしているのだと思います。(この考え方自体は否定しません) この場合、クリックイベントの手続きとしては次のようになります。(分かりにくくてすみません)  クリック処理の開始  ↓(1問目) ↓(2問目以降)  ↓    正誤判定  ↓     ↓   i を進める  ↓(i < 10) ↓(i = 10)  ↓    正解数を表示して終了  ↓ 問題を表示 1問目の流れで「i の問題を表示」するときに、i = 0 とするために、i の初期値は -1 としておきます。これが1問目か2問目以降かの判断材料になります。 また、i の役割は「現在の出題数」です。これは、クリックするたびに必ずインクリメントしなければ無限ループします。 Public i As Integer = -1 ' 出題中の問題数を示す値 Private Sub NextQuestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextQuestion.Click   ' i が -1 のとき(つまり、初回のクリック)   If i = -1 Then    【コントロールの準備】   ' i が -1以外のとき(つまり、回答後のクリック)   Else    【正誤判定】    【正解数の記憶】   End If i += 1 ' i をインクリメント(出題を次に進める)   ' i が10になった = 回答が10問終わった   If i = 10 Then     【結果の表示】     ここで i = -1 とすればまた最初からスタートします。   Else     【問題の表示】   End If End Sub 古典的ではありますが「流れ図」を書いてみると、やりたいことと実際の処理の流れの違いに気づけると思います。

ryousuke33
質問者

お礼

とてもわかりやすく大助かりでした。 本当にありがとうございました。

その他の回答 (1)

  • kyonn2008
  • ベストアンサー率22% (4/18)
回答No.1

なんかシッチャカメッチャカ‥ 実際のプログラムはきっともっとちゃんと作られているのだろうとして 質問にだけ答えると Question.Text = DataSet1.DataTable1(i).Question Answer1.Text = DataSet1.DataTable1(i).Answer1 Answer2.Text = DataSet1.DataTable1(i).Answer2 Answer3.Text = DataSet1.DataTable1(i).Answer3 Answer4.Text = DataSet1.DataTable1(i).Answer4 ↑この部分が i = i + 1 より前にあるからダメなんじゃないの?

関連するQ&A

  • 4択問題のプログラムでランダムに出題する処理で困っています

    現在私は画像のような4択の問題を解答し最後に何問正解していたかを表示するプログラムを作成しています。 解答を選択して「次の問題」ボタンをクリックすれば次の問題に移行する・・・というような流れです。 データテーブルに「問題(Question)」「選択肢(Answer1~4)」「解答(SelectAnswr)」「正解(CorrectAnswer」「正解の解説(Explanation)*今質問中では使用させません」を格納しています。 最終的な目標はデータテーブルに問題を300問用意しその中からランダムに100問出題して最後に結果を表示するプログラムを作成することです。 今どうすればランダムに出題しつつ同じ問題が出題されないようにするプラグラムを組めばいいのか壁にぶつかっています。 下記が「次の問題」ボタンのプログラムです。 Private Sub NextQuestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextQuestion.Click ' i が -1 のとき(つまり、初回のクリック) If i = -1 Then '選択肢を選択可能にする GroupBox1.Enabled = True 'NextQuestionのテキスト変換 NextQuestion.Text = "次の問題" ' i が -1以外のとき(つまり、回答後のクリック) Else '正誤確認 If Answer1.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ア" ElseIf Answer2.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "イ" ElseIf Answer3.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ウ" ElseIf Answer4.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "エ" End If If DataSet1.DataTable1(i).SelectAnswer = DataSet1.DataTable1(i).CorrectAnswer Then total = total + 1 End If End If i += 1 ' i をインクリメント(出題を次に進める) ' i が10になった = 回答が10問終わった If i = 10 Then MsgBox("あなたの正解数は10門中" & total & "問です!") Me.Close() Else '問題の読み込み Question.Text = DataSet1.DataTable1(i).Question Answer1.Text = DataSet1.DataTable1(i).Answer1 Answer2.Text = DataSet1.DataTable1(i).Answer2 Answer3.Text = DataSet1.DataTable1(i).Answer3 Answer4.Text = DataSet1.DataTable1(i).Answer4 'ラジオボタンを初期位置に戻す Answer1.Checked = True End If End Sub *変数iはPublicで宣言しています。 *最終目標は100問出題なのですが今は10問で動くプログラムを作成しています。 わかるかたがいましたら知恵をかしてください。 お願いします。

  • バグがとけません・・・

    現在私はVB2005で4択のクイズ形式のプログラムを作成しています。 データセットに問題、解答群などを格納しています。 それをフォームで表示してラジオボタンで4択のなかから正解と思うものを1つ選びボタンをクリックして次の問題へ移行する・・・というような流れのプログラムです。 今ためにしに問題を十問出題し最後の問題を終えたら10問中何問正解したかを表示するプログラムを作成しています。 データセットの内容はそれぞれ下記のとおりです。 Answer1~4・・・選択肢1~4 SelectAnswer・・・選択した選択肢を格納する CorrectAnswer・・・予めデータセットに格納してある正解 Loadで最初の一問目だけを読み込んで後はボタンを押すごとに問題が進んでいきますが全問正解するようにしても結果表示が正しく表示されません。 どこがバグかわかる方、もしくはさらに効率のいいコードがわかる方がいましたら助けてください。どうかよろしくお願いしますm(_ _)m Private Sub Form1_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load If IO.File.Exists(filePath) Then DataSet1.ReadXml(filePath) End If Question.Text = DataSet1.DataTable1(i).Question Answer1.Text = DataSet1.DataTable1(i).Answer1 Answer2.Text = DataSet1.DataTable1(i).Answer2 Answer3.Text = DataSet1.DataTable1(i).Answer3 Answer4.Text = DataSet1.DataTable1(i).Answer4 '正誤確認 If Answer1.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ア" ElseIf Answer2.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "イ" ElseIf Answer3.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ウ" ElseIf Answer4.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "エ" End If If DataSet1.DataTable1(i).SelectAnswer = DataSet1.DataTable1(i).CorrectAnswer Then total = total + 1 End If i = i + 1 End Sub Private Sub NextQuestion_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextQuestion.Click 'Static i As Integer = 0 'UStatic total As Integer = 0 'MsgBox(i)デバッグ '問題の読み込み Question.Text = DataSet1.DataTable1(i).Question Answer1.Text = DataSet1.DataTable1(i).Answer1 Answer2.Text = DataSet1.DataTable1(i).Answer2 Answer3.Text = DataSet1.DataTable1(i).Answer3 Answer4.Text = DataSet1.DataTable1(i).Answer4 '正誤確認 If Answer1.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ア" ElseIf Answer2.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "イ" ElseIf Answer3.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "ウ" ElseIf Answer4.Checked = True Then DataSet1.DataTable1(i).SelectAnswer = "エ" End If If DataSet1.DataTable1(i).SelectAnswer = DataSet1.DataTable1(i).CorrectAnswer Then total = total + 1 End If '終了 If i = 10 Then MsgBox("あなたの正解数はは10門中" & total & "問です!") Me.Close() End If i = i + 1 Answer1.Checked = True End Sub

  • 条件判断について教えて下さい。

    VB2008を使用している初心者です。 現在、RichTextBoxとCheckBoxとそれに対応したTextBoxを準備し、CheckBoxがTrueのTextBox.TextをRichTextBoxに代入するプログラムを作成しています。RichTextBoxにはCheckBoxをTrueにした分だけ複数のTextBox.Textを代入させています。ここまでのプログラムは下記コードで問題なく作動しています。 Button1を押す。 RichTextBox1.Clear() If Me.CheckBox1.Checked = True Then RichTextBox1.Text = TextBox1.Text End If If Me.CheckBox2.Checked = True Then If RichTextBox1.Text <> "" Then RichTextBox1.Text = RichTextBox1.Text & "・" End If RichTextBox1.Text = RichTextBox1.Text & TextBox2.Text End If ・ ・ ・ If Me.CheckBox20.Checked = True Then If RichTextBox1.Text <> "" Then RichTextBox1.Text = RichTextBox1.Text & "・" End If RichTextBox1.Text = RichTextBox1.Text & TextBox20.Text End If ここで問題なのですが、RichTextBox1への代入完了後、FalseにしたCheckBoxを再度True(代入時に選択したもののみ)にするコードをButton2に作成したいのですが上手くいきません。例えば下記のコードですと、RichTextBoxに1つだけTextBoxが入っている場合しかCheckBoxのTrueが戻りません。 If Me.CheckBox1.Checked = False Then If RichTextBox1.Text = TextBox1.Text Then Me.CheckBox1.Checked = True End If End If ・ ・ ・ If Me.CheckBox20.Checked = False Then If RichTextBox1.Text = TextBox20.Text Then Me.CheckBox2.Checked = True End If End If これはIf RichTextBox1.Text = TextBox1.Text Thenにしてしまっているためだと思いますが、これをどう修正したら良いかわかりません。もしお時間がある方みえましたらご教授お願いいたします。

  • モジュールを使ってフラグを作成

    Form1に問題をつくりラジオボタンでチェックできるようにして、Form2にチェックした内容の解答を表示させるプログラムを作りましたが、モジュール内でフラグを立てて、チェックをおこなう方法がわからないので、教えていただけませんか。 Form1 Private Sub Command1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click If Option1.Checked = True Then '鼻の長い動物 Form2.Label1.Text = "象です。" ElseIf Option2.Checked = True Then '首の長い動物 Form2.Label1.Text = "きりんです。" ElseIf Option3.Checked = True Then '足の速い動物 Form2.Label1.Text = "チーターです。" Else End If Form2 Private Sub Command1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Command1.Click Form2.Show() Me.Hide()

  • if文からcase文への置き換え

    ピクチャボックスをクリックしたら、チェック ボックスがチェックされるメソッドを作りたいと 思っています。 Private Sub PictureBox_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PictureBox1.Click,PictureBox2.Click 'ここから If sender Is PictureBox1 Then If Me.CheckBox1.Checked = False Then Me.CheckBox1.Checked = True Else Me.CheckBox1.Checked = False End If ElseIf sender Is PictureBox2 Then If Me.CheckBox2.Checked = False Then Me.CheckBox2.Checked = True Else Me.CheckBox2.Checked = False End If End If 'ここまで End Sub 上記のif文をCase文に置き換えたくて、 'ここから Select Case sender Case PictureBox1 If Me.CheckBox1.Checked = False Then Me.CheckBox1.Checked = True Else Me.CheckBox1.Checked = False End If Case PictureBox2 If Me.CheckBox2.Checked = False Then Me.CheckBox2.Checked = True Else Me.CheckBox2.Checked = False End If End Select 'ここまで 上記のように書き換えたのですが、エラーが出てしまいます(ビルドは通るのですが)。 Case文の使い方が間違っているんだとは思いますが、どこがどう 間違っているのがよくわかりません。 ご教授いただけないでしょうか?

  • CheckBoxがTrueの場合に表示をさせるには?

    VB2008を使用しています。 3つのCheckBox1~3とそれに対応した3つのTextBox1~3を準備し、 Buttonを押すとCheckBoxがTrueのものだけをRichTextBox1に表示 させたくて下記のプログラムを作成しました。 しかしCheckBox1とCheckBox3については上手く作動するのですが CheckBox2について不具合が発生します。 (不具合) CheckBox1=TrueでButtonを押すとRichTextBox1にTextBox1を表示。 その後、CheckBox3=TrueでButtonを押すとRichTextBox1にTextBox1. TextBox3と表示。 ここまでは良いのですが、 CheckBox2=TrueでButtonを押すとRichTextBox1にTextBox2を表示。 その後、CheckBox3=TrueでButtonを押すとRichTextBox1にTextBox2. TextBox2.TextBox3と表示されてしまいTextBox2の内容が重複して しまいまいます。 何か良い解決策がありましたら教えて下さい。 よろしくお願いいたします。 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click     If Me.CheckBox1.Checked = True Then RichTextBox1.Text = TextBox1.Text End If     If Me.CheckBox2.Checked = True Then If RichTextBox1.Text <> "" Then RichTextBox1.Text = RichTextBox1.Text & "."     End If RichTextBox1.Text = RichTextBox1.Text & TextBox2.Text     End If If Me.CheckBox3.Checked = True Then If RichTextBox1.Text <> "" Then RichTextBox1.Text = RichTextBox1.Text & "." End If RichTextBox1.Text = RichTextBox1.Text & TextBox3.Text End If End Sub

  • ファイルコピーで更新日時が変わってしまう。

    XP pro + Visual Basic 2008 で、ファイルをバックアップするためのソフトを作ろうとしています。 ListViewを二つ用意して、それぞれに対象となるフォルダー内のファイルを表示、チェックリストにチェックしたファイルを、互いのフォルダーにコピーする。のようなものを作っています。 しかしListView1からListView2へコピーを行うと、どういうわけか更新日時が数秒づれてコピーされてしまいます。逆の場合はづれが起こらないようです。 原因&解決法を教えてください。 コードは以下の通りです。    Dim i As Integer    Dim response As MsgBoxResult    i = 0    response = MsgBox("リスト1の選択ファイルをコピーしますか?", MsgBoxStyle.YesNoCancel, "確認")    If response = MsgBoxResult.No Then       GoTo CopyRist2    ElseIf response = MsgBoxResult.Cancel Then       Exit Sub    End If    Do Until i >= ListView1.Items.Count       If ListView1.Items(i).Checked = True Then          My.Computer.FileSystem.CopyFile(フォルダ1のパス & "\" & ListView1.Items(i).Text, _             フォルダ2のパス & "\" & ListView1.Items(i).Text, True)          ListView1.Items.RemoveAt(i)       Else          i = i + 1       End If    Loop CopyRist2:    i = 0    response = MsgBox("リスト2の選択ファイルをコピーしますか?", MsgBoxStyle.YesNoCancel, "確認")    If response = MsgBoxResult.No Then       Exit Sub    ElseIf response = MsgBoxResult.Cancel Then       Exit Sub    End If    Do Until i >= ListView2.Items.Count       If ListView2.Items(i).Checked = True Then          My.Computer.FileSystem.CopyFile(フォルダ2のパス & "\" & ListView2.Items(i).Text, _             フォルダ1のパス & "\" & ListView2.Items(i).Text, True)          ListView2.Items.RemoveAt(i)       Else          i = i + 1       End If    Loop 以上です。 よろしくお願いします。

  • jqueryでクイズを作成

    jqueryでクイズを作っているのですが、下のプログラムのような問題を書く部分(問題1、問題2...)のところに改行などを用いた長い文章を書きたいのですがどのようにしたらよいでしょうか? // answers の先頭が正答になるようにして下さい。選択肢はシャッフルして表示されます。 var questions = [ {'question': '問題1', 'answers': ['富士山', '愛鷹山', '天保山', '八ヶ岳']}, {'question': '問題2', 'answers': ['バラ', 'チューリップ', 'タンポポ', '百合']}, {'question': '問題3', 'answers': ['あららぎ', 'せんじょうがはら', 'せんごく', 'かんばる']}, {'question': '問題4', 'answers': ['宇宙人', '異世界人', 'ドイツ人', '未来人']} ]; Array.prototype.shuffle = function() { var i = this.length; while(i){ var j = Math.floor(Math.random()*i); var t = this[--i]; this[i] = this[j]; this[j] = t; } return this; }; var answers = []; var current_question_number; $.each(questions, function (i, question) { question.true_answer = question.answers[0]; question.answers.shuffle(); }); $(function() { showQuestion(0); $('#answer_button').click(function () { var answer = -1; $.each($('#answers input'), function (i, value) { if ($(value).is(':checked')) { answer = i; return false; } }); if (answer == -1) { $('#warning').slideDown(); return false; } $('#warning').slideUp(); answers[current_question_number] = questions[current_question_number].answers[answer]; if (current_question_number < questions.length - 1) { showQuestion(current_question_number + 1); } else { showResult(); } }); }); function showQuestion(question_number) { current_question_number = question_number; var question = questions[question_number]; $('#question_number').text((question_number + 1) + "/" + questions.length); $('#question_body').text(question.question); $('#answers').empty(); $.each(question.answers, function (i, value) { $('#answers').append($('<li/>').append($('<input type="radio" name="answer" id="answer' + i + '"/>')).append($('<label for="answer' + i + '"/>').text(value))); }); } function showResult() { $('#question_view').hide(); $.each(questions, function (i, question) { var is_true = answers[i] === question.true_answer; $('#results').append($('<tr/>') .addClass(is_true ? 'true' : 'false') .append($('<th/>').text(i + 1)) .append($('<td/>').text(answers[i])) .append($('<td/>').text(question.true_answer)) .append($('<td/>').text(is_true ? '○' : '×')) ); }); $('#result_view').show(); }

  • RichTextBoxに代入されたTextBoxの数を表示

    VB2008を使用しています。現在、10個のTextBoxとそれに対応するCheckBoxを作成し、チェックの入ったTextBox内の文字をRichTextBoxに代入するプログラムを作成しています。そこでRichTextBoxに代入されたTextBoxの数を別のTextBoxに表示させたいのですが何か良い方法はありますでしょうか?現在、下記のようにコードを組んであります。 Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click RichTextBox1.Clear() If Me.CheckBox1.Checked = True Then RichTextBox1.Text = TextBox1.Text If Me.CheckBox2.Checked = True Then If RichTextBox1.Text <> "" Then RichTextBox1.Text = RichTextBox1.Text & "・" End If RichTextBox1.Text = RichTextBox1.Text & TextBox2.Text ・ ・ ・ If Me.CheckBox10.Checked = True Then If RichTextBox1.Text <> "" Then RichTextBox1.Text = RichTextBox1.Text & "・" End If RichTextBox1.Text = RichTextBox1.Text & TextBox10.Text End If

  • エクセル ダブルクリックで処理日の入力

    お世話になります。 先般、お教え頂きました別のダブルクリックイベントプロシージャと 下記の当日の日付を入力するという処理を同じシート上で行いたいのですが、VBエディターにどのように記述したら良いかわかりません。 当方、かなりの初心者です。 よろしくご教授くださいませ。 【新しく加えたい処理】 Option Explicit Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Intersect(Target, Range("b4:C999")) Is Nothing Then Exit Sub If ActiveCell = "" Then ActiveCell = Date Cancel = True End If End Sub 【もともと使っている処理】 Private Sub Worksheet_BeforeDoubleClick(ByVal Target As Range, Cancel As Boolean) If Not Intersect(Target, Range("h1:h999")) Is Nothing Then With Target If .Value = "" Then .Value = "有" ElseIf .Value = "有" Then .Value = "無" ElseIf .Value = "無" Then .Value = "" End If End With ElseIf Not Intersect(Target, Range("i1:i999")) Is Nothing Then With Target If .Value = "" Then .Value = "要" ElseIf .Value = "要" Then .Value = "不要" ElseIf .Value = "不要" Then .Value = "" End If End With End If End Sub よろしくお願いします。