dポイントプレゼントキャンペーン実施中!

子供向けに暗算ドリルを作成しようと考えています。
VBAで、Range("A1")=InputBox("答えは?")と記述すれば、シート上にINPUTBOXが現れて、セルA1に答えを入力できますね。画面上にINPUTBOXを表示させるのは、違和感を感じてます。
「A1に問題を次々に表示させ」「A1に”答えは?”と表示させ」「A1に答えを入力させ」「A1に”正解です”表示」するような、スマートな入力方法はありますか?

A 回答 (4件)

こんにちは。



もしも、#1のコードで私のコンセプトを書いたのにも関わらず、そして、私のアドバイスがあまり役に立たないようでしたら、とりあえず、コードを見せてください。そして、どのようなご要望なのかお書きになっていただけませんか?

InputBox 以外では、イベント・ドリブン型マクロが最適だと思います。
    • good
    • 0
この回答へのお礼

ありがとうございました。
PC電源アダプター故障でT社にメンテに出したら、1月以上要し、ご返事できませんでした。
VBに関してかなり素人ですので、ご回答を理解できるよう努力したと思います。

お礼日時:2006/09/24 11:03

こんにちは。



全体のコードを見せていただきたいのですが、今は、ほとんど分かりません。

>乱数はRange("A1") = Int((Ketasuu * Rnd) + 1)を

Randomize は、使用しておられますか?

以下は、この方法では、無理です。

Do While Sheets("sheet1").Range("A1") = "答えは?"
Sheets("sheet1").Range("A1").Select
Loop

また、Sheets("sheet1") ではなくて、Worksheets("Sheet1") の方がよいです。トラブルはありませんが、Sheets オブジェクトとWorksheets オブジェクトは、若干違います。

入力待ち状態を、Do ~ Loop でも出来ないことはありませんが、いくら、Application 側に、キーのインターラプトを許しても、メモリ消費が激しいので、それは、やめたほうがよいです。イベント・ドリブン型マクロのほうが安全です。そうでなければ、UserForm やコントロールツールのTextBox で、KeyDown イベントで、キーを監視させるか、いくつかの方法があります。

>UserFormと次のコマンドの組み合わせも考えましたが、InputBoxと同様になってしまうので止めました。

今の段階では、どちらがどうという話は、水掛け論になってしまいますから、辞めておきますが、UserForm の使い方は、もう少し別だと思います。

なお、アルゴリズムというのは、先人が作ったもので、汎用性・移植性・拡張性のあるコードです。古代から、現代に至るものまで、いろんな時代のコンピュータに移植されてきたプログラムの一種です。VBAでは、めったにお目にかからないものです。
    • good
    • 0

こんにちは。



こんにちは。

すみません。一度、そのコードを試していただければ、ご質問に対する回答は分かっていただけると思ったのですが、こちらの勝手な思い込みでした。参考にはしていただけなかったようです。今回の私のプログラムは、ある程度、VBAの経験者でないと、その起動やメカニズムが分からないかもしれませんが。この種のものは、想像するより遥かに難しい種類のものだと思います。

>画面上にINPUTBOXを表示させるのは、違和感を感じてます。

一応、そのご質問に対する回答したと思っていたのですが、お分かりにならなかったようですね。

私の書いたコードでは、読み切れれば分かるはずですが、回答の結論からすると、InputBox の代わりにWorksheet_Change イベント・ドリブン型を使ったら、どうか、ということです。アプリケーション内部のものなら、反応スピードも速いし、使い勝手も悪くありません。

それに、VBA上の InputBox では、まず、文字が小さすぎます。ある程度の大きさがないと、認識スピードが落ちます。私の場合は、ワークシート上に、出現する問題のフォント・サイズは、20ポイントを使用しています。

完全に、Active X コントロール形式にするなら、UserForm上で、TextBox とLabel を駆使して行えばよいと思います。しかし、UserFormは若干、反応スピードが遅いように思います。UserFormは、VB のForm とは違って、ワークシートという巨大なメモリ消費があるし、Active X コントロールという、ある意味では、外部プログラム・ツールだからだと思います。

ちなみに、私は、VBA歴4年目に入りますが、アルゴリズムは、そんなに使いこなせるレベルではありません。今回の乱数発生のアルゴリズムは知りません。そういうものは、存在するのでしょうか?

この回答への補足

ありがとうございます。
VBAは年に数回使用する程度で深くは知らないのです。

乱数はRange("A1") = Int((Ketasuu * Rnd) + 1)を
使用してます。桁数で問題の難易度を調整しました。
色々試してみました。次のコマンドは、デバックモードでは有効なんですが、実行モードではループ状態になってしまいます。(入力を受け付けない状態)
Do While Sheets("sheet1").Range("A1") = "答えは?"
Sheets("sheet1").Range("A1").Select
Loop

UserFormと次のコマンドの組み合わせも考えましたが、InputBoxと同様になってしまうので止めました。
Worksheet_SelectionChange(ByVal target As Excel.Range)

補足日時:2006/08/23 12:31
    • good
    • 0

こんにちは。



それは、やはりセル上で行ったほうがよいですね。

InputBox は、あまり関心しません。

「A1に問題を次々に表示させ」
「A1に”答えは?”と表示させ」
「A1に答えを入力させ」
「A1に”正解です”表示」

問題を一旦、消してしまうのですか?
大人用でしたら、消してもよいと思いますが、ちょっと問題がシビアではありませんか?

問題は答えを入れて、合ったら消すという方法がよいのではないかと思います。

A2, B2, C3, 答えは、E2

 A  B    C   D   E  F
              正解です!/間違っています(^_^;)
 5  +   3  = (ここに答えを入れる)
                   

以下は、ご質問のイメージはかなり違うと思いますが、私の作ったものを、サイズダウンしてたものです。本当は、以下のコードに重複チェッカーと言って、同じものが出てくる場合に、それを回避するプログラムなどが付けられます。どちらかというと、これは、高齢者向けかもしれません。

試してみると、なんとなく、問題の出方に癖があるような気がします。一度、参考にしてみてください。

最初だけ、MakeQuestion で、問題を表示させてください。後は、続いて、問題が出てきます。10問終えると、続けるかどうか聞いてきます。

'---------------------------------------------------------------
'標準モジュール
'Option Explicit

Public Const QT_TOTAL As Integer = 10 '問題数
Public myCount As Variant 'カウント
Sub MakeQuestion()
'問題作成
Dim Arg1 As Variant
Dim Arg2 As Variant
Dim Arg3 As Variant
Dim ArgTmp As Variant
Dim Res As String
Dim Sn As Integer
Dim Ope As Variant
Dim Ret As Integer

'問題数のカウント
If myCount >= QT_TOTAL And Not myCount = Empty Then
 Ret = MsgBox("問題数は、" & myCount & "個行いました。" & vbCrLf & _
  "再び続けますか?", vbInformation + vbYesNo)
 If Ret = vbYes Then
   myCount = Empty
 ElseIf Ret = vbNo Then
   myCount = Empty
   Exit Sub
 End If
End If
Start:
'乱数発生
  Arg1 = Empty
  Arg2 = Empty
  ArgTmp = Empty
  '開始
  Randomize '乱数ジェネレータの初期化
  
  Arg1 = Int(Rnd() * 9) + 1
  Do
  ArgTmp = Int(Rnd() * 9) + 1
  Loop Until Arg1 <> ArgTmp
  Arg2 = ArgTmp
  '演算子選択
  Randomize
  Sn = Int(Rnd() * 4)
  Ope = Array("+", "-", "×", "÷")
  '演算
  
  Select Case Sn
   Case 0 '足し算
    Res = Arg1 + Arg2
   Case 1 '引き算
    If Arg1 < Arg2 Then
     ArgTmp = Arg2
     Arg2 = Arg1
     Arg1 = ArgTmp
     Res = Arg1 - Arg2
    Else
     Res = Arg1 - Arg2
    End If
   Case 2 '掛け算
    Res = Arg1 * Arg2
   Case 3
    If (Arg1 * Arg2) / Arg2 = 1 Then
     Do
      Arg1 = Int(Rnd() * 9) + 1
      Arg2 = Int(Rnd() * 9) + 1
     Loop Until ((Arg1 * Arg2) / Arg2) <> 1
    End If
    Arg1 = Arg1 * Arg2
    Res = Arg1 / Arg2
  End Select
  '問題数のカウント
  myCount = myCount + 1
  '問題表示
  Application.EnableEvents = False
  Range("A2").Value = Arg1
  Range("B2").Value = Ope(Sn)
  Range("C2").Value = Arg2
  Range("D2").Value = "= "
  Application.EnableEvents = True
End Sub

'-----------------------------------------------
'シートモジュール

'Option Explicit

Private Declare Sub Sleep Lib "kernel32" (ByVal dwMilliseconds As Long)

Private Sub Worksheet_Change(ByVal Target As Range)
Dim Arg1 As String, Arg2 As String, Arg3 As String
Dim Ret As Long
Dim Ope As String
 'E2に解答を入れます。
 If Target.Address(0, 0) <> "E2" Then Exit Sub
 If Target.Count > 1 Then Exit Sub
 Arg1 = Range("A2").Value
 Arg2 = Range("C2").Value
 
 Select Case StrConv(Range("B2").Value, vbWide)
 Case "-"
   Ope = "-"
 Case "×"
   Ope = "*"
 Case "÷"
   Ope = "/"
 Case "+"
   Ope = "+"
 Case Else
   Ope = "?"
 End Select
 If Ope = "?" Then
   Range("E1").Value = "エラーが起きていますので、もう一度問題を作ります。"
   Sleep 1500
   Range("E1:E2").Clear
   Range("E2").Select
   Call MakeQuestion
   Exit Sub
 End If
 If IsNumeric(Target.Value) Then
  Ret = Evaluate("=" & Arg1 & Ope & Arg2)
 Else
  Range("E1").Value = "答えをを入れてくださいね"
  Sleep 1500
  Range("E1:E2").Clear
  Range("E2").Select
  Exit Sub
 End If
 If Target.Value = Ret Then
   Range("E1").Font.ColorIndex = 3
   Range("E1").Value = "ハイ!正解です。 (残り" & CStr(QT_TOTAL - myCount) & "個)"
   Sleep 1500
   Range("E1:E2").Clear
   Range("E2").Select
   Call MakeQuestion
   Exit Sub
 Else
   Range("E1").Value = "間違えました。(^_^;)"
   Beep
   Sleep 1500
   Range("E1").Value = "もう一度答えを入れてください。"
   Sleep 1000
   Range("E1:E2").Clear
   Range("E2").Select
   Exit Sub
 End If
End Sub
    • good
    • 0
この回答へのお礼

ありがとうございます。
VBA浅くしか知らないのですが、出題のアルゴリズムは
出来ています。答え入力させるところだけ不本意でありながら、INPUTBOX使ってます。
ご回答いただいたどの部分が、「回答入力」に相当する箇所でしょうか?
If IsNumとか Exit Subを知らない素人です。
宜しく教示お願いします。

お礼日時:2006/08/23 08:25

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!


このQ&Aを見た人がよく見るQ&A