• ベストアンサー

ExcelのVBでタイピングゲームもどきを製作中なのですが・・・

はじめまして。 ExcelのVBでタイピングゲームもどきを作っているのですが、 どうしてもうまくできません。 いろいろ調べたのですが、解決できませんでした。 まだ途中なのですがこれができないと先に勧めません。 Sheet2からランダムに文章を選び表示し、 入力した文字が正しければ文字を下のテキストボックスに 落していくみたいな感じに作ろうとしています。 解決方法、直したほうがいいとこがりましたら回答のほう お願いします。 まるまるプログラムを変えたほうがいいような感じのときは どのようなプログラムにしたらいいのかお願いします。 Private Sub CommandButton1_Click() Dim n As Long Dim k As Long Dim L As Variant Dim X As Long Dim O As Variant Dim WrkRow As Long Dim WrkCol As Long Dim WrkRange As Variant With Sheets("Sheet2") WrkRow = .Cells(Rows.Count, 1).End(xlUp).Row WrkCol = .Cells(1, Columns.Count).End(xlToLeft).Column WrkRange = .Range("A1").Resize(WrkRow, WrkCol) End With L = "" TextBox1 = "" Randomize n = Int(Rnd() * 10) k = n + 1 TextBox1 = WrkRange(k, 1) TextBox2 = WrkRange(k, 2) O = k L = WrkRange(k, 2) X = 0 End Sub Private Sub CommandButton1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _ ByVal shift As Integer) If X > 6 Then Exit Sub KC = KeyCode If Chr(KC) = X Then X = X + 1 TextBox2 = Right(L, 7 - X) TextBox3 = Left(L, X) End If End Sub

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

  • ベストアンサー
  • o_chi_chi
  • ベストアンサー率45% (131/287)
回答No.6

#1です。 繰り返したいロジック(L = ""~X = 0)をサブプロシージャ(sGetWord)にして CommandButton1_KeyDownの終了判定後sGetWordをコールすればループできます。 そのときWrkRangeをパブリック変数にするのを忘れないように。 --- Private Sub CommandButton1_Click() (略) Call sGetWord End Sub If LCase(Chr(KC)) = C Then X = X + 1 TextBox2 = Right(L, B - X)’←文字数BからXを引いたLを表示 TextBox3 = Left(L, X)’←LのX番目の文字を表示 If X >= B Then rtn = MsgBox("もう一度実行しますか。", vbYesNo) If rtn = vbNo Then Exit Sub Call sGetWord Exit Sub End If End If

ren2012
質問者

お礼

遅れてすみません。 回答ありがとうございます。 無事完成することができました。 これまでアドバイスや指摘などありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (5)

  • o_chi_chi
  • ベストアンサー率45% (131/287)
回答No.5

#2です。 ウォッチで動作確認をしてみてください。 "c"を押下したときKCの値は"67"でChr(KC)とすると"C"に変換されます。 なので If LCase(Chr(KC)) = C Then もしくは If Chr(KC) = UCase(C) Then とすればTrueで判定されます。 ただし、大文字小文字を区別したければ細工が必要です。 mt2008さんの指摘も参考に。

ren2012
質問者

お礼

回答ありがとうございます。 If Chr(KC) = X Then を If LCase(Chr(KC)) = C Then に変えたら無事、求めていた状態になりました。 ありがとうございます。 最後に、1単語タイプし終えた後L = ""までループで戻すには、どうしたらいいのでしょうか? 時間があったら回答お願いします。

全文を見る
すると、全ての回答が全文表示されます。
  • mt2008
  • ベストアンサー率52% (885/1701)
回答No.4

No1です。 > 実行すると > If Chr(KC) = Mid(L, X + 1, 1) Then > の部分がエラーになってしまいます。 そうですか……どんなエラーでした? 「どんなエラー」だったかと言う情報が重要です。 > 一応私なりに思考したコードを貼ります。 > 指摘お願いします。 1.プロシジャー内の変数宣言にPrivateが使用されています。 修正前--- Private n As Long Private k As Long ↓ 修正後--- Dim n As Long Dim k As Long 2.文字数に達した時に抜けられません 修正前--- If X > B Then Exit Sub’←この場合、5文字より多くなったら終われ ↓ 修正後--- If X >= B Then Exit Sub’←この場合、5文字より多くなったら終われ これで動くと思いますがいかがですか? あと、変数宣言でVariant型は便利ですが、使いすぎると何の為の変数か判らなくなり、ミスの元になります、可能な限りちゃんとデータ型を指定するクセをつけた方が良いですよ。

ren2012
質問者

お礼

回答、指摘ありがとうございます。 エラー13だったと思います。 エラーって重要なんですね。 指摘&No5の回答をもとに修正したら無事、求めていた状態になりました。 ありがとうございます。 また、これからはVariantをあまり使わないようにしようと思います。 本当にありがとうございました。

全文を見る
すると、全ての回答が全文表示されます。
  • mt2008
  • ベストアンサー率52% (885/1701)
回答No.3

No.1です。 ちょっと間が空いてしまいましたのでもう解決されたかもしれませんが、念のために回答しておきます。 提示されたソースには大きな問題が2つあります。 1.変数の適用範囲の問題 Sub CommandButton1_Click で宣言した変数「L」「X」を、Sub CommandButton1_KeyDown でも使おうとしています。 Sub CommandButton1_Clickで宣言した変数は、そのSub内でしか使用できません。 Sub CommandButton1_KeyDownで使用している変数「L」「X」は、Sub CommandButton1_Click で宣言した変数とはまったく別な物です。 変数「L」「X」を、このモジュール内のプロシジャーで共有するばあい、プロシジャーの前で宣言します。 VBAは、デフォルトでは変数宣言をしなくても変数をいきなり使えるので、この様なミスが起こりがちです。モジュールの先頭に Option Explicit を入れて、変数は宣言しないと使用できないようにした方がミスは起こりにくくなりますのでお勧めです。 修正前--- Private Sub CommandButton1_Click() Dim n As Long Dim k As Long Dim L As Variant Dim X As Long Dim O As Variant : ↓ 修正後--- Option Explicit '←変数宣言強制 Private L As Variant '←変数Lはモジュール内で共有 Private X As Long '←変数Xはモジュール内で共有 Private Sub CommandButton1_Click() Dim n As Long Dim k As Long '←プロシジャー内でのL、Xの宣言は削る Dim O As Variant : 2.比較対象の問題 変数Xは、入力する文字列の位置だと思いますが、Sub CommandButton1_KeyDown 内では、その位置と、キー押下した文字を比較しています。 比較するのは、その位置にある文字とキー押下した文字だと思われます。 修正前--- If Chr(KC) = X Then ↓ 修正後--- If Chr(KC) = Mid(L, X + 1, 1) Then それと、Sub CommandButton1_KeyDown 内で、変数「KC」の宣言をするのもお忘れなく。

ren2012
質問者

お礼

遅れました。2度目の回答ありがとうございます。 問題は解決していません。 No.2の回答とも見比べながらやったのですがどうもうまくいきません。 実行すると If Chr(KC) = Mid(L, X + 1, 1) Then の部分がエラーになってしまいます。 一応私なりに思考したコードを貼ります。 指摘お願いします。 Option Explicit Private L As Variant'←共有 Private X As Long’←共有 Private Sub CommandButton1_Click() Private n As Long Private k As Long Dim WrkRow As Long Dim WrkCol As Long Dim WrkRange As Variant With Sheets("Sheet2") WrkRow = .Cells(Rows.Count, 1).End(xlUp).Row WrkCol = .Cells(1, Columns.Count).End(xlToLeft).Column WrkRange = .Range("A1").Resize(WrkRow, WrkCol) End With L = "" TextBox1 = "" Randomize n = Int(Rnd() * 10) k = n + 1 TextBox1 = WrkRange(k, 1)’←例)ココア TextBox2 = WrkRange(k, 2)’←例)cocoa L = WrkRange(k, 2)’←例)cocoa X = 0 End Sub Private Sub CommandButton1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, _ ByVal shift As Integer) Dim KC As Variant Dim B As Variant’←文字数 Dim C As Variant’←キーの位置(? B = Len(L)’←例)cocoaより、B=5文字 If X > B Then Exit Sub’←この場合、5文字より多くなったら終われ C = Mid(L, X + 1, 1)’←何文字目か(? KC = KeyCode If Chr(KC) = C Then X = X + 1 TextBox2 = Right(L, B - X)’←文字数BからXを引いたLを表示 TextBox3 = Left(L, X)’←LのX番目の文字を表示 End If End Sub

全文を見る
すると、全ての回答が全文表示されます。
  • o_chi_chi
  • ベストアンサー率45% (131/287)
回答No.2

>私が聞きたいこと の最初の方はリンク先で説明されていましたが。。。 プロシージャレベルではそのプロシージャを抜けた時点で変数の値は保存されず、メモリも解放されると記述されています。 でどうするかは、モジュールレベル変数もしくはパブリック変数に変えればよいということです。 どちらがよいかは設計者ではないので判断できかねます。 下記のリンク先も参考にして判断してください。 次ですが、文字数はLen関数を使用すれば取得できるので必要はないかと思います。 --- If X > Len(L) Then Exit Sub If Chr(KC) = Left(L,1) Then X = X + 1 TextBox2 = Right(L, Len(L) - X) TextBox3 = Left(L, X)

参考URL:
http://pc.nikkeibp.co.jp/article/NPC/20070803/279038/?P=1
ren2012
質問者

お礼

遅れてすみません。 回答ありがとうございます。 やっぱりキーを押しても無反応のままです。 Lenを使ってみました。 Lenを使うとTextBox2とTextBox3に文字数が表示されるような形になりました。 さらに、キーを押すとエラーになってしまいます。 この回答でLenを使うことで文字数を取得できるということを知りました。ありがとうございます。 ですが、問題が解決できなかったので残念です。

全文を見る
すると、全ての回答が全文表示されます。
  • mt2008
  • ベストアンサー率52% (885/1701)
回答No.1

もっと具体的に、何がどううまく行かないのかの説明が無いと誰も答えられないと思います。 さっとコードを眺めただけですが、変数の適用範囲について理解が不足しているように思えました。まずは、リンク先の説明をよく読む事をお勧めします。

参考URL:
http://support.microsoft.com/kb/141693/ja
ren2012
質問者

お礼

回答ありがとうございます。 参考URL読みました。 LやXの値がリセットされているということなのでしょうか? 理解力がなくすみません。 私が聞きたいことは、 ・この途中までのコードを実行したときにキーを押しても反映されず、 どうしたら反映されるか。 ・Lにローマ字の単語と字数を入れる方法。(検索ワードがわからないので)  例:L= Ball (4字)   みたいな感じで記憶する方法。 です。 説明不足ですみません。 回答の方よろしくお願いします。

全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • VB初心者です。コードの書き方が分かりません。

    VB初心者です。 VBで(zのn乗)-(xのn乗+yのn乗)の計算が出来るようにしたいのですが、答えが必ず-1になってしまいます。 Option Explicit On Public Class Form1 Dim x As Long Dim y As Long Dim z As Long Dim n As Long Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub Private Sub TextBox4_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox4.TextChanged End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click TextBox5.Text = (z ^ n) - (x ^ n + y ^ n) End Sub End Class 正しいコードの書き方を教えて下さい。 また特定の答えのときにメッセージを表示したいのですが、どうすればいいですか?

  • VBA書き込み数値の加算?

    エクセル2000のVBAにて下記のコードを書き込み コマンドボタン1にてエクセルに入力処理後 Label8数値の加算をエクセル関数SUNを使用して =SUM(E4:E1000)を行ったのですが、加算数値が0になってしまいます。 =E4+E5+E6・・・・だと加算した数値が表示されます。 (さすがにこれは避けたいです) 何か方法があると思いますが教えていただけますでしょうか? Dim i As Integer Dim k As Integer Private Sub CommandButton1_Click() With ActiveSheet For k = 4 To 1000 If .Cells(k, 1) = "" Then .Cells(k, 1) = TextBox1 .Cells(k, 2) = Label6 .Cells(k, 3) = Label7 .Cells(k, 4) = TextBox2 .Cells(k, 5) = Label8 TextBox1 = "" Label6 = "" TextBox2 = "" Label7 = "" Label8 = "" Exit Sub End If Next k End With End Sub Private Sub TextBox2_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = 13 Then Label8 = Application.WorksheetFunction.Round(Val(Label7) * Val(TextBox2), 0) Label8 = Format(Label8, "#,##0") End If End Sub

  • VB6→VS2005アップグレード後

    いつもお世話になっております。 VBを勉強中です。 VB6→2005にアップグレード後、下記のエラーが発生しました。 "オブジェクト参照がオブジェクト インスタンスに設定されていません。" 以前もこちらでアドバイスをいただき、 デザインの中でADDされているかどうかを確認し、解決に結びついたので 今回も同様かと思い、色々と行ったのですが解決しません。 frmapli_S3のデザイナ内に下記が存在しましたが 原因はここでしょうか? CType(Me.Frame1, System.ComponentModel.ISupportInitialize).EndInit() 以下はVB6での正常稼動時のソースです。 Public Sub ShowPermValue() Dim Textbox As Textbox Dim i As Long: Dim j As Long: Dim k As Long For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Set Textbox = frmapli_S3.Controls("text" & k) Textbox.Text = PermValue(k) Next Next End Sub Public Sub SetPermValue() Dim Textbox As Textbox Dim i As Long: Dim j As Long: Dim k As Long For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Set Textbox = frmapli_S3.Controls("text" & k) PermValue(k) = Textbox.Text Next Next 下記はVB2005アップグレード時のソースです。 Public Sub ShowPermValue() Dim Textbox As TextBox Dim i, j, k As Integer For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Textbox = CType(frmapli_S3.Controls("text" & k), TextBox) TextBox.Text = PermValue(k) Next Next End Sub Public Sub SetPermValue() Dim Textbox As TextBox Dim i, j, k As Integer For i = 0 To 19 For j = 1 To 8 k = i * 10 + j Textbox = CType(frmapli_S3.Controls("text" & k), TextBox) PermValue(k) = Textbox.Text   ←ここでエラー Next Next End Sub

  • Excel VBA ユーザフォームの検索について

    添付の画像のようなユーザフォームを作っています。 TextBox1に検索ワードを入力して、CommandButton1をクリックすると、下のComboBox1に一覧が出るようにしたいと思い、ほかのサイトから下記のコードを見つけて、作ってみました。参照先のsheet2を表示しているときは大丈夫なのですが、別のシートを選んでいるとエラーになります。 sheetは3つあり、それぞれ違うリストが入力されています。今回はsheet2のリストを参照したいのですが、最初はsheet1が表示されている状態で実行したいです。 エラーの内容は 実行時エラー9 インデックスが有効範囲にありません。 コチラがコードです。 Private Sub UserForm_Initialize() Dim i As Long, imax As Long Dim tbl() As Variant imax = ThisWorkbook.Worksheets("sheet2").Cells(Rows.Count, "A").End(xlUp).Row ReDim tbl(imax) For i = 1 To imax tbl(i) = Range("A" & i).Value Next i With ComboBox1 .List() = tbl() End With End Sub Private Sub CommandButton1_Click() Dim i As Long, imax As Long Dim tbl() As Variant Dim cnt As Long, j As Long j = -1 With ThisWorkbook.Worksheets("sheet2") imax = .Cells(Rows.Count, "A").End(xlUp).Row cnt = Application.CountIf(Range("A1:A" & imax), "*" & TextBox1.Text & "*") ReDim tbl(cnt) For i = 1 To imax If InStr(.Range("A" & i), TextBox1.Text) > 0 Then j = j + 1 tbl(j) = Range("A" & i).Value ←この部分がエラーになる End If Next i End With With ComboBox1 .List() = tbl() End With End Sub どこを直せば良いか、教えてください。 よろしくお願いします。

  • このコードはどこが間違っていますか?(至急)

    急ぎのため再度の質問失礼します。 (zのn乗)-(xのn乗+yのn乗)の計算をさせて、答えが0のときにメッセージを表示したいのですが、どのようなコードを書けばいいのでしょうか? Option Explicit On Public Class Form1 Dim x As Long Dim y As Long Dim z As Long Dim n As Long Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click Me.Close() End Sub Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End Sub Private Sub TextBox2_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox2.TextChanged End Sub Private Sub TextBox3_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox3.TextChanged End Sub Private Sub TextBox4_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox4.TextChanged End Sub Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click x = TextBox1.Text y = TextBox2.Text z = TextBox3.Text n = TextBox4.Text TextBox5.Text = (z ^ n) - (x ^ n + y ^ n) If (TextBox5 .Text= 0) Then Label6.Visible = True End If End Sub Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load End Sub Private Sub Label6_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Label6.Click End Sub End Class このコードだと答えが必ず-1になってしまうのですが、どこを直せばいいのでしょうか? 正しいコードを教えて下さい。 よろしくお願いします。

  • VBでタイピングゲーム作成

    Private Sub TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged If TextBox1.Text = Label1.Text Then Label1.Text = "haradamunetoki" Label2.Text = "原田宗時" TextBox1.Text = "" Else Label3.Text = "違います" Private TextBox1_TextChanged(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles TextBox1.TextChanged End If If TextBox1.Text = Label1.Text Then Label1.Text = "katakurakojuro" Label2.Text = "片倉小十郎" TextBox1.Text = "" Else Label3.Text = "違います" End If ――最初ラベル1にはdatemasamune、ラベル2には伊達政宗と表示してあって、主に判断の基準となるのはラベル1ですが、 最初のEnd If文までの間で繰り返しのような感じになってしまっていて 次の片倉小十郎に行くことができません。 先生に話しを聞いたところ、文法をよく理解していないとのこと…。 次のif文にいくにはどうしたらいいのでしょうか?

  • Excel2000 VBA シート名の変更

    なかなかうまくいかずに困っています。 Excel2000  OS:WindowsXp ユーザーフォーム(UserForm1)上に ・Textbox1 ・Textbox2 ・Commandbutton1 があります。 Commandbutton1をクリックすると、Textbox1とTextbox2の値をつなげた文字列を、 アクティブなワークシートの名前にしたいと思っています。 今現在の、うまく動かないコードは以下のとおりです。 Private Sub CommandButton1_Click() 'ユーザーフォーム上のCommandButton1 Dim snday As Variant 'Textbox1に入力される、『日』を取得するための変数 Dim snyoubi As Variant 'Textbox2に入力される『曜日』を取得するための変数 Dim namae As Variant 'シート名になる変数。 Dim Sh As Worksheet snday = UserForm1.TextBox1.Value snyoubi = UserForm1.TextBox2.Value namae = snday & snyoubi Sh.Name = namae End Sub これを実行すると、 実行時エラー’91’ オブジェクト変数または withブロック変数が設定されていません のエラーが出ます。 Sh.Name = namae のところを with ActiveSheet ~End with で挟んでみてもだめでした。 どなたかご教授ねがえませんか。 よろしくお願いいたします。

  • エクセルBVAのフォーム式のKeyCode~の意味がわかりません

    エクセルBVAです Private Sub TextBox1_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) If KeyCode = vbKeyDown Then KeyCode = 0 End If End Sub ヘルプをみると キーを押したとき、およびキーを離したときに続いて発生します。KeyDown イベントはキーを押すと発生し、KeyUp イベントはキーを離すと発生します。 キーってenterのことですかね? なら、 If KeyCode = vbKeyDown Then KeyCode = 0 End If で、KeyCodeを0ににするってどういうことでしょうか?

  • MSForms.ReturnInteger

    Excel VBAで 違うSubから textbox_keypress をコールしたいのですが、 vbKeyReturnを受け渡せません。 ****************************************** Private Sub StartButton_Click() Dim KeyCode As MSForms.ReturnInteger If EngTypeStartButton.Caption = "" Then KeyCode.Value = vbKeyReturn <---ここでエラーになる。 Call TextBox_KeyDown(KeyCode, 0) End If End Sub ****************************************** 『実行エラー91 オブジェクト変数またはWithブロック変数が設定されていません』 と表示されます。 vbKeyReturnの代わりに13としても結果は同じです。 受け側のSubは以下のような始まりです。 Private Sub TextBox_KeyDown(ByVal KeyCode As MSForms.ReturnInteger, ByVal Shift As Integer) このSubは正常に動作しています。 どなたか私の間違いを教えていただけないでしょうか? よろしくお願いいたします。

  • 値渡しについて

    UserForm1で以下のように求めた値「R」を UserForm2に渡すにはどのようにすればよいのでしょうか。 **************************************** <UserForm1(コード)> Public R As Integer ----------------------------------- Private Sub CommandButton1_Click()    Dim N As Integer        :    N = TextBox1.Text    R= N * 2 + 3        : End Sub **************************************** <UserForm2(コード)> Private Sub CommandButton1_Click()   Dim i As Integer       :   For i = 4 To R       :   Next i       : End Sub **************************************** どなたか教えて下さい。

専門家に質問してみよう