はじめまして。
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
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
遅れてすみません。
回答ありがとうございます。
無事完成することができました。
これまでアドバイスや指摘などありがとうございました。
No.5
- 回答日時:
#2です。
ウォッチで動作確認をしてみてください。
"c"を押下したときKCの値は"67"でChr(KC)とすると"C"に変換されます。
なので
If LCase(Chr(KC)) = C Then
もしくは
If Chr(KC) = UCase(C) Then
とすればTrueで判定されます。
ただし、大文字小文字を区別したければ細工が必要です。
mt2008さんの指摘も参考に。
回答ありがとうございます。
If Chr(KC) = X Then
を
If LCase(Chr(KC)) = C Then
に変えたら無事、求めていた状態になりました。
ありがとうございます。
最後に、1単語タイプし終えた後L = ""までループで戻すには、どうしたらいいのでしょうか?
時間があったら回答お願いします。
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型は便利ですが、使いすぎると何の為の変数か判らなくなり、ミスの元になります、可能な限りちゃんとデータ型を指定するクセをつけた方が良いですよ。
回答、指摘ありがとうございます。
エラー13だったと思います。
エラーって重要なんですね。
指摘&No5の回答をもとに修正したら無事、求めていた状態になりました。
ありがとうございます。
また、これからはVariantをあまり使わないようにしようと思います。
本当にありがとうございました。
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」の宣言をするのもお忘れなく。
遅れました。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
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/27 …
遅れてすみません。
回答ありがとうございます。
やっぱりキーを押しても無反応のままです。
Lenを使ってみました。
Lenを使うとTextBox2とTextBox3に文字数が表示されるような形になりました。
さらに、キーを押すとエラーになってしまいます。
この回答でLenを使うことで文字数を取得できるということを知りました。ありがとうございます。
ですが、問題が解決できなかったので残念です。
No.1
- 回答日時:
もっと具体的に、何がどううまく行かないのかの説明が無いと誰も答えられないと思います。
さっとコードを眺めただけですが、変数の適用範囲について理解が不足しているように思えました。まずは、リンク先の説明をよく読む事をお勧めします。
参考URL:http://support.microsoft.com/kb/141693/ja
回答ありがとうございます。
参考URL読みました。
LやXの値がリセットされているということなのでしょうか?
理解力がなくすみません。
私が聞きたいことは、
・この途中までのコードを実行したときにキーを押しても反映されず、
どうしたら反映されるか。
・Lにローマ字の単語と字数を入れる方法。(検索ワードがわからないので)
例:L= Ball (4字)
みたいな感じで記憶する方法。
です。
説明不足ですみません。
回答の方よろしくお願いします。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・人生のプチ美学を教えてください!!
- ・10秒目をつむったら…
- ・あなたの習慣について教えてください!!
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・【大喜利】【投稿~9/18】 おとぎ話『桃太郎』の知られざるエピソード
- ・街中で見かけて「グッときた人」の思い出
- ・「一気に最後まで読んだ」本、教えて下さい!
- ・幼稚園時代「何組」でしたか?
- ・激凹みから立ち直る方法
- ・1つだけ過去を変えられるとしたら?
- ・【あるあるbot連動企画】あるあるbotに投稿したけど採用されなかったあるある募集
- ・【あるあるbot連動企画】フォロワー20万人のアカウントであなたのあるあるを披露してみませんか?
- ・映画のエンドロール観る派?観ない派?
- ・海外旅行から帰ってきたら、まず何を食べる?
- ・誕生日にもらった意外なもの
- ・天使と悪魔選手権
- ・ちょっと先の未来クイズ第2問
- ・【大喜利】【投稿~9/7】 ロボットの住む世界で流行ってる罰ゲームとは?
- ・推しミネラルウォーターはありますか?
- ・都道府県穴埋めゲーム
- ・この人頭いいなと思ったエピソード
- ・準・究極の選択
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
【Excel】BeforeCloseを毎回呼...
-
vbaでmsgboxの位置を指定
-
エクセルVBAでNumLockキーの状...
-
VBAが得意な方 助けてください...
-
Excel:アドイン(ThisWorkbook)...
-
Application.Runエラー(1004)
-
access2010 コマンドまたはアク...
-
別シートのマクロを実行する方法
-
マクロ 戻るボタンを押したらシ...
-
エクセルVBAで、ボタンの文字を...
-
Access終了時にマクロまたはVBA...
-
エクセルのマクロボタンが編集...
-
マクロとモジュールの違いを教...
-
InputBox内の表示について
-
Workbook_Openを起動時以外に呼...
-
ウィンドウサイズ・場所のレジ...
-
エクセル:保存するときに、標...
-
アクセスのマクロについて
-
Excel VBA サブルーチン関連
-
エクセル VBA SendKeys ループ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
エクセルVBAでNumLockキーの状...
-
エクセルVBA フォームShowでオ...
-
vbaでmsgboxの位置を指定
-
【Excel】BeforeCloseを毎回呼...
-
VBAが得意な方 助けてください...
-
エクセルのダブルクリックで
-
smartvisionで録画失敗が頻発
-
HULFT完了コードについて
-
エクセル2003のマクロでコマン...
-
フォームを作成すると同時にイ...
-
ExcelのVBでタイピングゲームも...
-
ブレークポイントについて教え...
-
VBAでフォームにおけるコマンド...
-
Excel:アドイン(ThisWorkbook)...
-
別シートのマクロを実行する方法
-
Application.Runエラー(1004)
-
エクセルのマクロボタンが編集...
-
Access終了時にマクロまたはVBA...
-
InputBox内の表示について
-
エクセルVBAで、ボタンの文字を...
おすすめ情報