• ベストアンサー

エクセルVBA、入力しないと閉じないInputBox

必ず何かを入力しないと閉じないInputBoxを作ろうと思います。 以下のコードで入力がなければ閉じないというか、Line:に戻るので、何度でも現れるInputBoxになるようですが、このやり方は正しいですか? 通常はどうやるのでしょうか? Sub test() Dim a line: a = Application.InputBox("必ず入力して下さい。", "Input!") If Len(a) = 0 Or a = False Then GoTo line MsgBox "有難う。" & a & " ですね。", , "(o。_。)oペコッ" End Sub

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

  • ベストアンサー
  • j_nishiz
  • ベストアンサー率26% (183/697)
回答No.1

手元のExcel2007で動かしてみたらちゃんと動きますね。 (我ながら暇だ。) 間違ってませんが、Goto文は避けるように、というのがお約束ですので Sub test2() Dim a Do Until Len(a) > 0 a = Application.InputBox("必ず入力して下さい。", "Input!") Loop MsgBox "有難う。" & a & " ですね。", , "(o。_。)oペコッ" End Sub こんなんでどうでしょう。

merlionXX
質問者

お礼

早速有難うございました。Do~Loopを使うんですね。 Do Until Len(a) > 0 And a <> False でやってみました。 ぜんぜん別の話ですが、キャンセルのFalseと手入力のFalseを区別してくれないのが困りものです・・・・。

その他の回答 (6)

回答No.7

エキスパートさん、こんにちは。 (1)Do Until Len(a) > 0 And a <> False の件 次のコードを試してみてください。 '------------------------------------------------ Sub Test()  Dim A, B  A = Application.InputBox(vbLf & "キャンセルをクリックせよ")  B = Application.InputBox(vbLf & "false を入力せよ")  MsgBox _   "キャンセル (A)" & vbLf & vbLf & _   "A = false -> " & (A = False) & vbLf & _   "A = ""false"" -> " & (A = "false") & vbLf & vbLf & _   "false入力 (B)" & vbLf & vbLf & _   "B = false -> " & (B = False) & vbLf & _   "B = ""false"" -> " & (B = "false") End Sub '----------------------------------------------------- この結果から分かるように、手入力されたfalseは、 恰も論理値のFalseと文字列の"false"の2つの値をとっているような振る舞いをしていることが分かります。 ですから、 >Do Until Len(a) > 0 And a <> False この a<>false では、キャンセルのfalseと手入力の"false"を区別できないわけです。 で、手入力のfalseを区別するためには Do Until (Len(a) > 0 And a <> False) Or a = "false"  このように、a="false"を追加してやればいいことになります。 ーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーーー (2)Loopのところに条件をセットするの件 >どう試しても同じ結果にしかならないようなのです 今回の場合は結果は変りません。 なので、「今回のような場合には」と言ったわけです。 >Do Until Len(a) > 0 And VarType(a) <> vbBoolean > a = Application.InputBox("必ず入力して下さい。", "Input!") >Loop 上記では条件になるaの値は、Do Loopの中で初めて決まるにも拘わらず いきなりDoのところで判定をしていますのでそこが拙いのです。 次をお試しください。 '----------------------------------------------- Sub bbb()  Dim a  a = 5  Do Until Len(a) > 0 And VarType(a) <> vbBoolean   a = Application.InputBox("必ず入力して下さい。", "Input!")  Loop  MsgBox a & " ですね。" End Sub '------------------------------------------ 今回はDo Loopに入る前には、Do Loopを抜けるような、aの値は入ってないのでたまたま上手くいったわけですが、 もし上記のように、Do Loopに入る前に、Do Loop を抜ける値がaに入っていた場合はどうでしょう。 何もしないうちにDo Loopを抜けることになります。 どうでしょう、納得できましたでしょうか。 もし、エキスパートさんが分からないと思ってることと、 当方の意図してるところが違ってましたら、ペコリ~、ということで。(^^;;; 以上です。  

merlionXX
質問者

お礼

お大師、kobouzu_suさま、いつもありがたい教えを感謝いたします。 よく分かりました。 これからもよろしくお願いします。

  • KenKen_SP
  • ベストアンサー率62% (785/1258)
回答No.6

賑わってますねw 既に解決済みだと思いますので、お遊びのキワモノコードを。。。 入力しないと OK も キャンセル もクリックできない、InputBoxEx です。 ' // 標準モジュール Option Explicit Private Declare Function SetTimer Lib "user32.dll" ( _    ByVal hWnd As Long, _    ByVal nIDEvent As Long, _    ByVal uElapse As Long, _    ByVal lpTimerFunc As Long) As Long Private Declare Function KillTimer Lib "user32.dll" ( _    ByVal hWnd As Long, _    ByVal nIDEvent As Long) As Long Private Declare Function FindWindow Lib "user32.dll" Alias "FindWindowA" ( _    ByVal lpClassName As String, _    ByVal lpWindowName As String) As Long Private Declare Function GetDlgItem Lib "user32.dll" ( _    ByVal hDlg As Long, _    ByVal nIDDlgItem As Long) As Long Private Declare Function EnableWindow Lib "user32.dll" ( _    ByVal hWnd As Long, _    ByVal fEnable As Long) As Long Private Declare Function SendMessage Lib "user32.dll" Alias "SendMessageA" ( _    ByVal hWnd As Long, _    ByVal wMsg As Long, _    ByVal wParam As Long, _    ByRef lParam As Any) As Long Private Const WM_GETTEXT As Long = &HD Private Const MAX_PATH  As Long = 256 Private msInputBoxTitle As String Private mfFirstCall   As Boolean ' // 強制入力 InputBox Public Function InputBoxEx( _     ByVal Prompt As String, _     Optional ByVal Title As String = "Microsoft Excel" _ ) As String   Const INTERVAL As Long = 10     Dim TimerID As Long   mfFirstCall = True   msInputBoxTitle = Title   TimerID = SetTimer(0&, 0&, INTERVAL, AddressOf CallBackInputBoxEx)   InputBoxEx = InputBox(Prompt, Title)   Call KillTimer(0&, TimerID) End Function ' // Timer コールバック関数 Private Sub CallBackInputBoxEx( _   ByVal hWnd As Long, _   ByVal uMsg As Long, _   ByVal idEvent As Long, _   ByVal dwTime As Long _ )     Dim hEdit  As Long   Dim hBtn1  As Long   Dim hBtn2  As Long   Dim sBuffer As String   Dim lPos  As Long     hWnd = FindWindow("#32770", msInputBoxTitle)   If hWnd > 0 Then     hEdit = GetDlgItem(hWnd, &H1324)     hBtn1 = GetDlgItem(hWnd, &H1&)     hBtn2 = GetDlgItem(hWnd, &H2&)     If mfFirstCall Then       Call EnableWindow(hBtn1, 0&)       Call EnableWindow(hBtn2, 0&)       mfFirstCall = False     Else       sBuffer = String$(MAX_PATH, Chr(0))       Call SendMessage(hEdit, WM_GETTEXT, MAX_PATH, ByVal sBuffer)       sBuffer = Replace$(sBuffer, Chr(0), "")       If Len(sBuffer) > 0 Then        Call EnableWindow(hBtn1, 1&)       Else        Call EnableWindow(hBtn1, 0&)       End If     End If   End If End Sub ' // 以下は使い方サンプル Sub SampleProc()   Dim s As String   s = InputBoxEx("入力しないと閉じることができない?", "強制入力Sample")   MsgBox s End Sub

merlionXX
質問者

お礼

KenKen_SPさま、いつもお世話様です。 これは入力しないとボタンを全部無効にしてしまうのですね! 凄いです。 有難うございました。

回答No.5

エキスパートさん、こんばんは。 毎日、暑ーーーーーーい、ですねぇ。 既に解決済みのようですが、例によってお節介。(^^;;; >If Len(a) = 0 Or a = False Then GoTo line とか >Do Until Len(a) > 0 And a <> False これがなぜ拙いのかお分かりでしょうか? それが分からなければ本当の意味での解決にはならないのではないのでしょうか。 是非、そこのところを考えてみてください。 そして、今回のような場合に、Do Loopを使うときは >Do  ●Until Len(a) > 0 And VarType(a) <> vbBoolean● >a = Application.InputBox("必ず入力して下さい。", "Input!") >Loop 上記のように、条件●をDoのところに書かずに >Do >a = Application.InputBox("必ず入力して下さい。", "Input!") >Loop  ●Until Len(a) > 0 And VarType(a) <> vbBoolean● このように、Loopのところに書くべきです。 ちょっと考えてみると分かると思います。 スーパーエキスパートWendy02さんの回答でもそうなってますよね。 そしてまた、Goto文は場合によってはそれを使うことで、シンプルなコードを書くことができますので、一概には使用禁止、とはならないと考えます。 それはともあれ、少なくとも最初の件は是非考えてみてください。 そんなんは、百も承知の助、ということであれば、あちゃー、というほかありませんが。。(^^;;; 以上です。  

merlionXX
質問者

お礼

> これがなぜ拙いのかお分かりでしょうか? > それが分からなければ本当の意味での解決にはならないのではないのでしょうか。 > 是非、そこのところを考えてみてください。 すみません、ずっと考えていましたがわかりません。 > そして、今回のような場合に、Do Loopを使うときは これも、 Sub aaa() Do a = Application.InputBox("必ず入力して下さい。", "Input!") Loop Until Len(a) > 0 And VarType(a) <> vbBoolean MsgBox a & " ですね。" End Sub と Sub bbb() Do Until Len(a) > 0 And VarType(a) <> vbBoolean a = Application.InputBox("必ず入力して下さい。", "Input!") Loop MsgBox a & " ですね。" End Sub を、どう試しても同じ結果にしかならないようなのです・・・ おてあげです。 すみません。

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

こんにちは。 混乱させるつもりではありませんが、キャンセル不可なら、このようにしても出来ます。 Sub test() Dim a As Variant '明示的にデータ型は入れます。 Do  a = Application.InputBox("必ず入力して下さい。", "Input!", Type:=2) Loop Until a <> "" And VarType(a) <> vbBoolean MsgBox "有難う。" & a & " ですね。", , "(o。_。)oペコッ" End Sub ただ、プログラミングとしては、通常、ユーザーの選択肢としては、キャンセル・クリックの余地を残しておいたほうがよいと思います。 >何度でも現れるInputBoxになるようですが、このやり方は正しいですか? ネットの中では、goto 方式は、理屈抜きに批判する人がいるというだけで、現実の問題としては、goto 方式でも悪くはありません。 かつて、「構造化プログラミング」とは、「goto」を排除することだと、一般プログラマーが誤解するようになったからで、実際問題、「goto」を抜きに書いて、それだけで、構造化プログラムが達成するわけでもありません。概して、VBAやVBで、「goto」を連発してコードを書く人は、技術的に低いのは事実ですが、「なし」にして、必ずしも、ベストとは言えません。 それと、InputBox 関数は、レガシーですから、現在では、なるべく、戻り値のデータ型を指定して、InputBox メソッドを使うようにしたほうがよいですね。

merlionXX
質問者

お礼

> InputBox 関数は、レガシーですから レガシーって古いシステムのことですね? ありがとうございました。

  • yukika-37
  • ベストアンサー率39% (26/66)
回答No.3

>たしかに文字列のFalseは認識されますが、今度はキャンセルが可能になってしまい、入力しないと閉じないInputBoxではなくなっています。 キャンセル不可にしたいということでしょうか? それでしたら、こんな感じでしょうか。 Sub test4() Dim a Do a = InputBox("必ず入力して下さい。", "Input!") Loop Until Len(a) > 0 MsgBox "有難う。" & a & " ですね。", , "(o。_。)oペコッ" End Sub

merlionXX
質問者

お礼

なるほど、Application.InputBoxではなくInputBoxを使うんですね。これならキャンセルで空白が返りますから間違いませんね。

  • yukika-37
  • ベストアンサー率39% (26/66)
回答No.2

Sub test3() Dim a Do a = Application.InputBox("必ず入力して下さい。", "Input!") Loop Until Len(a) > 0 If VarType(a) <> vbBoolean Then MsgBox "有難う。" & a & " ですね。", , "(o。_。)oペコッ" End If End Sub #1さんとほぼ同じです。 文字列として"False"を入力した場合はメッセージボックスが出るようにしてみました。

merlionXX
質問者

お礼

有難うございます。 たしかに文字列のFalseは認識されますが、今度はキャンセルが可能になってしまい、入力しないと閉じないInputBoxではなくなっています。

merlionXX
質問者

補足

Sub test3() Dim a Do Until Len(a) > 0 And VarType(a) <> vbBoolean a = Application.InputBox("必ず入力して下さい。", "Input!") Loop MsgBox "有難う。" & a & " ですね。", , "(o。_。)oペコッ" End Sub で、文字列のFalseは認識されますがキャンセル不可となり、うまく行きました。 ありがとうございます。

関連するQ&A

  • エクセルVBA Inputboxについて教えてください。

    InputBoxの使い方について教えてください。 テストで下記のように書いてみました。 Sub input_test2() ans = InputBox("質問!適当に数字を入れてね") MsgBox Application.WorksheetFunction.IsNumber(ans), vbInformation, "入力判定" If Application.WorksheetFunction.IsNumber(ans) Then If ans = 0 Then MsgBox "入力されたのは、 0", vbInformation, "回答" If ans = 1 Then MsgBox "入力されたのは、 1", vbInformation, "回答" If ans = 2 Then MsgBox "入力されたのは、 2", vbInformation, "回答" If ans = 3 Then MsgBox "入力されたのは、 3", vbInformation, "回答" If ans >= 4 Then MsgBox "入力されたのは、 4以上", vbInformation, "回答" Else MsgBox "入力は数字でしてください!", vbExclamation, "お願い" End If End Sub 1.入力が数値ならTRUEがかえると思ったのですが、何を入れてもFALSEしかかえりません。どこがまずいのでしょうか? 2.表示されるInputBoxのサイズが随分横に長いのですが、サイズを変える方法はあるのでしょうか? 3.MsgBoxの"入力判定"や”回答”ようにInputBoxにも最上行に日本語を表示させる方法はないでしょうか? 以上、よろしくお願いいたします。

  • エクセルのInputBoxについて教えてください。

    エクセル2010です。 InputBoxについて教えてください。  負数以外の数値を受け取りたいのです。 以下のようにやってみました。 Sub test001() Dim ans As Double ans = Application.InputBox("数値を入力", Type:=1) If ans = False Then MsgBox "キャンセル" Exit Sub ElseIf ans < 0 Then MsgBox "負数は不可。" Call test Else MsgBox ans & "を受け取りました。" End If End Sub 一応、これで動くのですが、問題は数値0を入力された場合です。 0はFalseと認識されるようで、キャンセルとなってしまいます。0は0という数値で受け取りたいのです。 試行錯誤の結果、Type:=1をやめ、変数ansをVariantにして If ans = “False” Then と、Falseをダブルクォーテーションでくくると、0を数値としてくれるようです。でも理屈がわかりません。変数ansにキャンセルボタンで帰ってくるのはBooleanのFalseであり、Stringの”False”ではないと思うのですが。 Sub test002() Dim ans ans = Application.InputBox("数値を入力") If ans = "False" Then MsgBox "キャンセル" & TypeName(ans) Exit Sub ElseIf ans = "" Then MsgBox "未入力" & TypeName(ans) Call test002 ElseIf Not IsNumeric(ans) Then MsgBox "数値ではありません。" & TypeName(ans) Call test002 ElseIf ans < 0 Then MsgBox "負数は不可。" & TypeName(ans) Call test002 Else MsgBox ans & "を受け取りました。" & TypeName(ans) End If End Sub あと、もうひとつ質問は、数値以外の入力があった場合、再度入力させるためいちいちCall test002 を入れてますが、このやり方でただしいのでしょうか?

  • VBAのinputboxで何もいれずに[OK]を押した時エラーになります

    よろしくお願い致します。 EXCELのVBAで「inputbox」を使ってセルを選択させたいと考えております。 下記のコードだと「キャンセル」や「×」で閉じられた時はmsgbox「キャンセル」が出てExit subするのですが、何も入力しないで「OK」を押した場合がどうしてもエラー(入力した数式は正しくありません)になります。 いろいろ調べて試したのですがどうしてもできず困っています。 どなたか教えてください。 Sub test() Dim myAns As Range On Error Resume Next Set myAns = Application.InputBox(Prompt:="セルを選択してください。", Title:="セル選択", Type:=8) On Error GoTo 0 If myAns Is Nothing Then MsgBox "キャンセル" Exit Sub ElseIf myAns = "" Then MsgBox "最低1つは選択してください" Exit Sub Else MsgBox myAns.Address(0, 0) End If End sub

  • エクセルマクロでinputboxメソッドゼロ入力

    エクセル2007です。 以下のマクロで、inputboxメソッドで質問させると、キャンセルボタンを押すと、うまいぐあいに止まります。 しかし、0を押しても、止まってしまいます。本当は、C2にゼロと表示させたいのです。 Sub 練習() Dim myR myR = Application.InputBox(prompt:="数量を入力しなさい", Type:=1) If myR = False Then Exit Sub Range("C2").Value = myR End Sub

  • マクロ inputbox ブランクで入力した時

    いつも回答して頂きありがとうございます。 InputBoxに何も入力せず、OKを押してしまった場合、マクロの処理を終了させたいのですが、どうしたらよろしいでしょうか?宜しくお願い致します。 Sub 名前を入力する() Dim a As Long a = Application.InputBox("班を数字で入力して下さい。", Type:=1) If a = 0 Then MsgBox "キャンセルされました。", vbOKOnly Exit Sub End If With ActiveSheet .Range("E4:F5").Value = Worksheets("名前一覧").Cells(2, a).Value End With End Sub

  • InputBox関数について

    VBAの勉強中です。 教えてください。 INPUTBOX関数で、何も入力しないでの入力も可、とするコードはどうなるでしょうか。 言葉を変えて言えば、入力ボックスが未入力の状態でOKボタンを押すということです。 例えば以下のようにすると、当然ながら「キャンセル」と判断されます。 Sub Test()  Dim myData As String  myData = InputBox("入力してください")   If myData = "" Then     MsgBox "キャンセル"   Else     MsgBox "入力OK"   End If End Sub ■■尚、今回は、メソッドではなくて関数での質問になりますのでその点よろしくお願いします。  

  • InputBoxからの掛け算

    InputBoxに【計算式を入力してください 例)3*5】、そのあとMsgBoxにその答えを【答えは~】と表示させるには、どうプログラミングすればいいですか? Sub 電卓() henji = InputBox("計算式を入力してください 例)3*5") MsgBox a End Sub というところまでは何となくわかるのですが、これに何を足せばいいのでしょうか? 教えてください、お願いします。

  • VBA inputbox関数について

    質問をさせてください。 VBA inputbox関数にて 数字を入力をし、その数字を元に挿入を行うというものを施しています。 そして下記の内容で実際は動くのですがどうしても疑問点が浮かんできます。 それはinputbox関数には宣言をしないと文字列として処理されますよね? なので、宣言をlongにして整数化をしています。 しかし、If "1" <= buf1 <= "65536" Thenの部分で 数字に""(ダブルコーテーション)を入れないとうまく作動しません。 例えば「0」を入力しても正の処理へ行います。 ダブルコーテーションで囲んでいる数値は文字列として認識されるはず・・ 入力は数値として宣言をしているのだからダブルコーテーションはいらないのではないんでしょうか? また、もし数字ではなく、記号などを入力をしてしまった場合の偽の処理へいくにはどうすれば いいでしょうか? 恐れ入りますがよろしくお願いいたします。 Sub test() Dim buf1 As Long buf1 = InputBox("コピー先の列番号を入力してください") If "1" <= buf1 <= "65536" Then Cells(buf1, 1).EntireRow.Insert Else MsgBox "正しい列番号を入力してください" Exit Sub End If End Sub

  • excel vba inputbox

    初心者です。質問させて下さい。 inputboxでhelpを参照すると、typeの指定は以下ですが、 値 意味 0 数式 1 数値 2 文字列 (テキスト) 4 論理値 (True または False) 8 セル参照 (Range オブジェクト) 16 #N/A などのエラー値 64 数値配列 やはり、図形を選択させる事は不可能でしょうか? 具体的には、 マクロ実行中にinputboxを表示させて、図形を選択させ、図形名を表示させて、その図形を既定の図形に設定させたいと思っています。 図形を一つ選択した状態ならば、その図形の名前は以下のコードのように取得できるのですが、inputboxでは図形がなぜか選択できないです。 そもそも、inputboxを使用しようと思ったのは、他のコマンドやツール等が非選択状態になること、またマクロ実行の途中で一時中断することができ、これらの条件は便利だし必要だと思ったからです。 inputboxは何かで設定を変える等で図形を選択できるのでしょうか?無理でしょうか? また、代替的なものは他にあるのでしょうか? Sub testA() Dim Def As Object Set Def = Excel.Selection If TypeOf Def Is Excel.Rectangle Then MsgBox (Def.Name) End If End Sub 無理な質問かもしれませんが、どなたか御教授お願い致します!

  • エクセルVBAで

    全シート保護(保護の解除)のコードなんですが、パスワードを求めない形にするには下記をどうすれば良いのですか? Sub 全シート保護の設定() Dim Sh As Worksheet x = Application.InputBox("パスワードを入力して下さい", Type:=3) For Each Sh In Worksheets Sh.Protect (x) Next Sh End Sub Sub 全シート保護の解除() Dim Sh As Worksheet On Error GoTo ErLine Do x = Application.InputBox("パスワードを入力して下さい", Type:=3) Loop While x = "False" For Each Sh In Worksheets Sh.Unprotect Password:=x Next Sh Exit Sub ErLine: y% = MsgBox("パスワードが違います ! 終了します", 48) End Sub 毎度すみませんがよろしくお願いします。

専門家に質問してみよう