• ベストアンサー

エクセル(VBA)上でINPUTBOX以外の入力方法ないでしょうか?

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

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

  • ベストアンサー
  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.4

こんにちは。 もしも、#1のコードで私のコンセプトを書いたのにも関わらず、そして、私のアドバイスがあまり役に立たないようでしたら、とりあえず、コードを見せてください。そして、どのようなご要望なのかお書きになっていただけませんか? InputBox 以外では、イベント・ドリブン型マクロが最適だと思います。

kmasumi
質問者

お礼

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

その他の回答 (3)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.3

こんにちは。 全体のコードを見せていただきたいのですが、今は、ほとんど分かりません。 >乱数は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では、めったにお目にかからないものです。

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.2

こんにちは。 こんにちは。 すみません。一度、そのコードを試していただければ、ご質問に対する回答は分かっていただけると思ったのですが、こちらの勝手な思い込みでした。参考にはしていただけなかったようです。今回の私のプログラムは、ある程度、VBAの経験者でないと、その起動やメカニズムが分からないかもしれませんが。この種のものは、想像するより遥かに難しい種類のものだと思います。 >画面上にINPUTBOXを表示させるのは、違和感を感じてます。 一応、そのご質問に対する回答したと思っていたのですが、お分かりにならなかったようですね。 私の書いたコードでは、読み切れれば分かるはずですが、回答の結論からすると、InputBox の代わりにWorksheet_Change イベント・ドリブン型を使ったら、どうか、ということです。アプリケーション内部のものなら、反応スピードも速いし、使い勝手も悪くありません。 それに、VBA上の InputBox では、まず、文字が小さすぎます。ある程度の大きさがないと、認識スピードが落ちます。私の場合は、ワークシート上に、出現する問題のフォント・サイズは、20ポイントを使用しています。 完全に、Active X コントロール形式にするなら、UserForm上で、TextBox とLabel を駆使して行えばよいと思います。しかし、UserFormは若干、反応スピードが遅いように思います。UserFormは、VB のForm とは違って、ワークシートという巨大なメモリ消費があるし、Active X コントロールという、ある意味では、外部プログラム・ツールだからだと思います。 ちなみに、私は、VBA歴4年目に入りますが、アルゴリズムは、そんなに使いこなせるレベルではありません。今回の乱数発生のアルゴリズムは知りません。そういうものは、存在するのでしょうか?

kmasumi
質問者

補足

ありがとうございます。 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)

  • Wendy02
  • ベストアンサー率57% (3570/6232)
回答No.1

こんにちは。 それは、やはりセル上で行ったほうがよいですね。 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

kmasumi
質問者

お礼

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

関連するQ&A

  • エクセルVBA InputBoxで入力欄を*****

    VBAのInputBoxでパスワードを入力させるようにしているのですが、入力欄に入れた文字は当然ながらそのまま表示されます。 これをいかにもパスワードの入力のように入力数字を****と表示させることはできないものでしょうか?

  • inputboxの日本語入力切替について

    VBAのinputbox関数についての質問です inputboxを使ってデータの入力をしたいのですが、日本語入力のONとOFFを自動的に切り替えられる記述はありませんでしょうか。 現在の記述は sub 入力() Dim simei As String simei = InputBox("氏名を入力してください") range("b5").Value = Simei End su のような感じです。inputboxを表示するまえに、言語バーの日本語入力がONの状態になるようにしたいのですが…。よろしくお願いします。

  • エクセル上のVBA

    当方、VBAまるっきり初心者です(触りはじめて3日くらい)。 エクセルはある程度理解しているつもりですが… バージョンはエクセル2000です。 他シートのセルのひとつに入力すれば、 別シートのセルがそれを参照したうえで 値として表示出来るようにならないでしょうか。  今のところ、以下のような状況です。 step01 sheet1のセルA1に任意の数値(整数限定です)を入力。 step02 sheet2のセルA1に、sheet1のセルA1の数値を用いて     MOD関数で余りを出す。 step03 sheet2のセルB2に以下のVBAによって     step02の余りを値として表示。      Private Sub Worksheet_Change(ByVal Target As Range)        Range("b2").Value = Range("a1")      End Sub  これだとsheet1の数字を変えても、 sheetの切替後sheet2のセルB2に 表示される値が変わってくれません。  最初の入力(step01の入力)をおこなえば sheet2のセルB2まで値が変わってくれるような方法を 教えていただけないでしょうか。  拙い説明で申し訳ありませんが、よろしくお願いします。

  • エクセルVBAの記述で・・・OTL

    エクセルVBAの記述で・・・OTL VBA初心者です。 まず、私が記述した内容を書きます。 Sub 実践練習() Dim tuika As String tuika = Application.InputBox( _ Title:="追加", _ Prompt:="追加する内容を入力して下さい。", _ Left:=650, _ Top:=100, _ Type:=2) If Worksheets("Sheet2").Range("G10").Value <> " FALSE " Then MsgBox "OKです", vbOKOnly + vbDefaultButton2, "追加完了" With Worksheets("Sheet2") .Range("G10").Value = tuika LastRow = Worksheets("Sheet3").Range("A" & Rows.Count).End(xlUp).Row + 1 Worksheets("Sheet3").Range("A" & LastRow).Value = Worksheets("Sheet2").Range("G10").Value End With Else MsgBox "入力が不足しています。", vbOKOnly + vbCritical, "入力ミス" End If End Sub() 完成させたいことは・・・ Sheet1に存在するInputbox(ボタン)を使用し、 Sheet2のG10にFALSE以外が入力されたときは、 MsgBox追加完了のダイアログを表示してSheet2のG10値をSheet3のA列に順番に転送させる。 もしFALSEが入力されてしまったら、 MsgBox入力ミスを表示させて、 Sheet2のG10の値(FALSE)を削除しなさい。 と、記述したいのです。 勿論、上記の記述は完成していません(泣 どなたか、ご教授の程、何卒宜しくお願い致します。 (上記の完成型をお待ちしてます m(_ _)m ) 【環境】 OS:WindowsXP Pro Excel:2003

  • エクセルのInputBoxのことで

    InputBoxに入力された値を、セルに反映させるVBAを知りたいのですが。 a bbb c ddddd 上記のように、スペースで区切って入力し、上記のケースなら、 A1 に a 、A2 に bbb 、A3 に c、A4 に ddddd と反映されるようにしたいのですが。 よろしくお願い致します。

  • Inputboxに開始番号と終了番号を入力し印刷

    InputboxにInputboxに印刷する番号の開始番号と終了番号を入力して、 自動で印刷できるようにしたいと考えています。 シートにはセルG6に数字を入力すれば、VLOOKUPで印刷内容を 変更できるように設定しています。 以下のようなVBAを作成しました。 しかし、Loopが止まらないです。 どうすればよいでしょうか? また他に間違いは有りますでしょうか? Sub 印刷() Do a = InputBox("開始番号を入力") z = InputBox("終了番号を入力") Range("G6") = a a = a + 1 ActiveWindow.SelectedSheets.PrintOut Copies:=1 Loop Until a = z End Sub

  • inputboxを使ったセルの指定について教えてください。

    セルA5を指定したいときに、Range("A5").Selectとするのでなく、 A1+inputboxで入力した数字”4”を使って 指定するにはどうしたらよいでしょうか? 教えてください。よろしくお願いします。 毎日入力するデータがあり、数箇所のシート、 セルにコピーペーストしています。 (どのワークブック、シートでも1日はA5、2日はA6、 と1行づつ下げていっています)。 Caseを使用して1から31までひとつひとつコピー元、 貼り付け先を指定しようとしましたが、 あまりにも膨大のため、入力ミスの元になると思いやめました。 そこで、何日のデータなのかをinputboxで入力しており、 それを利用して、セルの指定をしようと考えましたが、 手元の解説書やネットでも見つかりませんでした。

  • Excel 2007 VBA にて式の入力方法不明

    VBAで式の入力方法がわかりません、教えていただけませんか? 当方初心者です。よろしくお願い致します。 別の、組合せSheetの U7 セルに 半角で 2012 と数字が入力してあります。 この数字を、 平成23年度 と表示が出来るようにしたいのです。 別のSheetの A1 セルに 下記の 数式をマクロで入力したいのですがうまくできません。 =" 平成"&JIS(組合せ!U7-1989)&"年度" マクロでは、 Range("A1").Formula = "=" 平成"&JIS(組合せ!U7-1989)&"年度"  と入力するのですが、うまく受け付けてくれません。

  • EXCEL VBAのInputBox

    VBA初心者のため、質問がうまくできないかもしれませんが よろしくお願いします。 ユーザーから文字列を入力してもらうためInputBoxを使用しました。キーボードのDを押したら、Input Boxを表示させるようにしたのですが、入力エリアにDが表示されてしまいます。また、プログラムを実行後から押されたキーの文字もすべて入力エリア表示されてしまいます。入力エリアを空白の状態で表示させたいのです。方法を教えてください。

  • エクセル inputboxの入力を編集モードで

    エクセルのvbaでinputboxで入力させているのですが規定値のすぐあとに続けて入力したいのですが、一回クリックしないとセルの入力のような編集モードになりません。何百と続けて入力したいのでその度クリックしないですむよにinputboxの入力が 編集モードにすることができますでしょうか? 例えば 2019/10/ が規定値で / のすぐあとに数字をいれたいのですが 2019/10/の部分が反転されているので一回クリックしなければなりません。

専門家に質問してみよう