[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]
『インプットボックスをキャンセル』(りんご)
いつもお世話になっております。 本日も宜しくお願い致します。
ユーザーフォーム内の「Button3」を押すとインプットボックスが表示され、 入力したコードを元に必要な情報をフォーム上に表示させています。
Private Sub Button3_Click() '検索
Dim Searchkey As String Dim SearchArea As Range Dim Foundcell As Range
Searchkey = Application.InputBox(Prompt:="コードを入力して下さい", Type:=2)
Set SearchArea = Sheets("台帳").Range("A:A")
Set Foundcell = SearchArea.Find(What:=Searchkey, SearchOrder:=xlByRows, _ LookAt:=xlWhole, MatchCase:=False)
If Foundcell Is Nothing Then ’データがない時 MsgBox "データなし", vbCritical GoTo ExitHandler
End If
With Foundcell Me.Box1.Value = .Value 'コード Me.Box2.Value = .Offset(0, 4).Text '完了予定月 Me.Box3.Value = .Offset(0, 1).Text '契約日 Me.Box4.Value = .Offset(0, 2).Text '完了日 Me.Box5.Value = .Offset(0, 3).Text '担当 Me.Box6.Value = .Offset(0, 5).Text 'お客様名
End With
ExitHandler: Set SearchArea = Nothing Exit Sub
End Sub
この処理の際に、 1、インプットボックスで条件一致の場合はデータを表示 2、誤ったコードが入力されたら「データなし」を通知(未入力で実行した場合も) 3、インプットボックスのキャンセルを選択したら「キャンセルしました」と通知 以上、3つの選択を行いたいのです。 現状ですと「キャンセル」選択時は、「データなし」が通知されます。 色々調べたのですが、「空白」と「キャンセル」は同じ扱いになるようで 「キャンセル」だけを別の処理と捉えたいのですが、どのようにすれば宜しいのでしょうか?
皆様のお知恵をお貸し下さい。宜しくお願い申し上げます。
< 使用 Excel:Excel2013、使用 OS:Windows7 >
こちらを参考にしてはどうでしょうか。 http://officetanaka.net/excel/vba/tips/tips37.htm (マナ) 2014/06/15(日) 16:34
マナ様
ご回答ありがとうございました。 こちらのサイトは何度も見ていたのですが、 「InputBoxメソッドなら、[キャンセル]ボタンがクリックされた結果のFalseと、 空欄("")のまま[OK]ボタンがクリックされたのを判別できます。それだけの話です。」 この部分がいまいち理解出来ずにいます。
先ほど記述したコードに追加しました↓
If TypeName(Searchkey) = "Boolean" Then MsgBox "キャンセル" End If
結果、キャンセル時に「キャンセル」と表示された後に「データなし」と表示されました。
恐らく、 If Foundcell Is Nothing Then ’データがない時 この部分を存在しないコードが入力されたらとさせれば上手くいくような気がします。 Searchkey と Foundcell がある為か難しく感じてしまってます。 もう少し頑張ってみます。ありがとうございました。
(りんご) 2014/06/15(日) 17:45
Sample9は理解できますか? (マナ) 2014/06/15(日) 18:14
マナ様 ご連絡遅くなりました。申し訳ありません。 時間がたち、Sample9の部分をもう1度読み直してみました。 昨日とは違い、少し理解できたような気がしたので下記のように作成しました。
Private Sub Button3_Click() '検索 Dim Searchkey As Variant Dim SearchArea As Range Dim Foundcell As Range
Searchkey = Application.InputBox(Prompt:="コード入力") If Searchkey = False Then MsgBox "キャンセルされました" Exit Sub End If
If Searchkey = "" Then MsgBox "コードを入力して下さい"
End If
Sheets("台帳").Select Set SearchArea = Sheets("台帳").Range("A:A")
Set Foundcell = SearchArea.Find(What:=Searchkey, SearchOrder:=xlByRows, _ LookAt:=xlWhole, MatchCase:=False)
If Foundcell Is Nothing Then MsgBox "該当するデータはありません" GoTo ExitHandler End If --------------------以下、省略----------------------------
上記で希望通りに動きましたが何か問題点等はないでしょうか? 宜しくお願い致します。 (りんご) 2014/06/16(月) 14:22
Sub test() Dim ret As String
Do If ret = "False" Then MsgBox "キャンセルしました" Exit Sub ElseIf ret = "" Then ret = Application.InputBox("コードを入力してください") Else Exit Do End If Loop
MsgBox "コードが入力されたので検索を実行します"
End Sub
(マナ) 2014/06/16(月) 20:06
ちょっと気になったので・・・。 気になったのは、InputBoxメソッドのキャンセルクリックの判断の仕方です。 りんごさんが最初に投稿された
>If TypeName(Searchkey) = "Boolean" Then > MsgBox "キャンセル" >End If
この戻り値をTypeName関数で判断する手法をどうして変えられたのかなあ?
というのが気になった点です。もっとも全体としては、本当に細かい事なんですが (細かい事が気になるのが 僕の悪い癖 ←杉下右京風)。
> 「InputBoxメソッドなら、[キャンセル]ボタンがクリックされた結果のFalseと、 >空欄("")のまま[OK]ボタンがクリックされたのを判別できます。それだけの話です。」 >この部分がいまいち理解出来ずにいます。
VBAでダイアログを表示させて、ユーザーに文字を入力要求する機能には、
InputBox関数と
ApplicationオブジェクトのInputBoxメソッドがあることは、マナさんご紹介のリンク先にもあります。
InputBox関数
Sub test1() Dim mes As String mes = InputBox("何か入力してください") If mes = "" Then MsgBox "キャンセルボタンが押されました" Else MsgBox "入力されたデータは " & mes End If End Sub
InputBox関数は、上記のコードのようにキャンセルボタンを押された時は、空欄("")が返ります。
これだと、未入力の状態で OKボタンを押された時とキャンセルボタンを押された時の 区別がつかない事になります。
その証拠に 上記のtest1で何も入力しないでOKボタンを押すと 「キャンセルボタンが押されました」と表示されます。
厳密にこのInputBoxの機能にこだわれば、 「OKボタンが押されたら、入力されたデータを返し(例え、空欄でも)、キャンセルボタンが押されたら、キャンセルボタンが押されたことが認識できる」という仕様でなければなりませんよね?
InputBox関数では厳密に判断できないので ApplicationオブジェクトのInputBoxメソッドなら出来るよ という事なんです(実は、InputBox関数でもできますが)。 が・・・。
りんごさんが2回目に投稿されたキャンセルをFalseで判断する方法だと
Sub test2() Dim mes As Variant mes = Application.InputBox("何か入力してください") If mes = False Then MsgBox "キャンセルボタンが押されました" Else MsgBox "入力されたデータは " & mes End If End Sub
これだと、確かに空白とキャンセルボタンの区別は付きますよね!!
でもこれだと、 「False」という文字列を取得できません、キャンセルボタンを押したと 判断されてしまいます。
OKボタンが押されたら、入力された文字列を返さなければならないのに・・・。
文字列の"False"でキャンセルを判断すると、少しはよくなりますが(Test2は、Falseもfalseもダメ)
Sub test3() Dim mes As String mes = Application.InputBox("何か入力してください") If mes = "False" Then MsgBox "キャンセルボタンが押されました" Else MsgBox "入力されたデータは " & mes End If End Sub
これでも 文字列 「False」をOKボタンで取得できません。
よって、最初にりんごさんが投稿したTypeName関数を使う方法がよいと思うのです。
Sub test4() Dim mes As Variant mes = Application.InputBox("何か入力してください") If TypeName(mes) = "Boolean" Then MsgBox "キャンセルボタンが押されました" Else MsgBox "入力されたデータは " & mes End If End Sub
これだと、空欄もFalseもOKボタンを押せば、文字列として取得できますし、キャンセルボタンの判断もしてくれます。
でも、りんごさんがコードを変えたのがFalseとした方がわかりやすい という理由なら、納得もできます。
test4を以下のようなコードにすると、わかりやすさも少し克服できると思います。
Sub test5() Const Cancel As Variant = False Dim mes As Variant mes = Application.InputBox("何か入力してください") If mes = Cancel Then MsgBox "キャンセルボタンが押されました" Else MsgBox "入力されたデータは " & mes End If End Sub
***************************************
因みにInputBox関数でも以下のようにすると、空白文字列でOKボタンを押した場合とキャンセルボタンの区別をしてくれます。
これは、StrPtr関数の意味や String型の変数の内部構造を知らないと意味は理解できないかもしれませんが・・・。
Sub test6() Const Cancel As Long = 0 Dim mes As String mes = InputBox("何か入力してください") If StrPtr(mes) = Cancel Then MsgBox "キャンセルボタンが押されました" Else MsgBox "入力されたデータは " & mes End If End Sub
以上です。
(ichinose) 2014/06/17(火) 05:12
ありがとうございます。TANAKAさんよりわかりやすい説明です!
0が入力されたとき区別がつかないと、いつからか思い込んで、 今まで、Type2のときは、TypeNameで判定しないようにしていました。
(マナ) 2014/06/17(火) 07:56
マナ様・ichinose様
様々なご指導をありがとうございます。 ichinose様のご指摘を解読しようとゆっくり時間をかけて読んでみました。 まだ少し私の知識が追い付いていかない部分もあるのですが、 おっしゃている事は何となくですが、理解できたような気がします。
コードを変えた理由は、自分のコードに自信がなかったので マナ様に教えて頂いたサイトを参考に作成してみただけです。 まだ、どちらが適切か。という判断に自信が持てないので。。。
マナ様に教えて頂いたループコードを参考にますます希望通りのものができました。 本当にありがとうございました。 今後とも宜しくお願い致します! (りんご) 2014/06/17(火) 13:31
[ 一覧(最新更新順) ]
YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki.
Modified by kazu.