InputBoxメソッドで「戻り値空白」と「キャンセル」の処理を分ける
「InputBox関数を使ったプロシージャを用意したのですが実際の使用状況に対応できません」という相談を受けました。
具体的にどんな事に困っているのか教えてもらいました。ポイントは2つです。
- テキストボックスが空白のままOKボタンを押される事がある(処理が用意できてない)
- 「数値で入力・・・」と書いていてもテキストボックスに文字列が入力されてしまう
InputBox関数では「テキストボックスが空白の時の戻り値」と「キャンセルボタンを押した時の戻り値」が同じです。
ボタンの操作に応じてその後の処理を区別したくても戻り値が同じでは処理をコントロールできません。
もう1つはテキストボックスに入力される値です。
InputBox関数では値を数値で受け取る仕様のコードの中で文字列が入力されるとエラーが出て処理が止まってしまいます。
こんな時はInputBox関数を使わずに「InputBoxメソッド」+「IsNumeric関数」を使いましょう。
課題のような環境をカバーすることができますよ。
最初にInputBoxメソッドとIsNumeric関数を紹介します。その後事例の中で冒頭の2つの課題を解決させていきます。
最後のまとめでは今回用意するコードを継続して使う為のメンテナンス方法について解説しています。
関連記事
MsgBoxもInputBoxのようにダイアログボックスを使ってユーザーの行動をコントロールする事ができます。
MsgBoxの基本的な使い方VBA-11マクロ内でMsgBoxとIFステートメントを組み合わせる
データを保存するVBA|MsgBoxの「保存」ボタンを使わずにデータをSaveする
関連書籍
こちらの書籍にはInputBoxメソッドについての説明が掲載されています。
掲載ページとしてはそんなに多くないのですが事例と共に使用されているのでイメージしやすく分かりやすいです。
おすすめ電子書籍(Kindleストア)はこちらです。
デュアルディスプレイで作業されている方は電子書籍の方が扱いやすいです。お試しください。
InputBoxメソッド
まずはInputBoxメソッドの構文とパラメータを見ていきましょう。
構文
Microsoftのドキュメントとほとんど同じですが少しだけ加工しています。
InputBoxメソッドはApplicationオブジェクトに用意されたメソッドです。
パラメータ
パラメータはMicrosoftのドキュメントをそのまま引用します。
Microsoft:Application.InputBox メソッド (Excel)
名前 必須 / オプション データ型 説明 Prompt 必須 String ダイアログ ボックスに表示するメッセージを指定します。 この引数には、文字列、数値、日付、またはブール値を指定できます (Microsoft Excel では表示される前に、自動的に値を文字列型 (String) に変換します)。 最大長は 255 文字です。それ以外の場合、プロンプトは表示されず、アプリケーションのメソッドはすぐにエラー 2015 を返します。 Title 省略可能 Variant ダイアログ ボックスのタイトルを指定します。 この引数を省略すると、既定値の「入力」がタイトル バーに表示されます。 Default 省略可能 Variant ダイアログ ボックスが最初に表示されるときに、テキスト ボックスに表示される値を指定します。 この引数を省略すると、テキスト ボックスが空で表示されます。 この値は Range オブジェクトを指定できます。 Left 省略可能 Variant 画面の左上隅を基準として、ダイアログ ボックスの X 座標をポイント単位で指定します。 Top 省略可能 Variant 画面の左上隅を基準として、ダイアログ ボックスの Y 座標をポイント単位で指定します。 HelpFile 省略可能 Variant 対象の入力ボックスで使うヘルプ ファイルの名前を指定します。 引数 HelpFile および HelpContextID が共に指定されていれば、ダイアログ ボックス内に [ヘルプ] ボタンが表示されます。 HelpContextID 省略可能 Variant 引数 HelpFile で指定したヘルプ ファイル内のヘルプ トピックのコンテキスト ID 番号を指定します。 Type 省略可能 Variant 返されるデータの型を指定します。 この引数を省略すると、ダイアログ ボックスは文字列 (テキスト) を返します。 InputBoxメソッドではTypeというパラメータが用意されています。InputBox関数には無いです。
パラメータの一番最後に表示されているTypeを指定する事で戻り値の値をコントロールする事ができます。
Microsoft:Application.InputBox メソッド (Excel)
値 説明 0 数式 1 数値 2 文字列 (テキスト) 4 論理値 (True または False) 8 セル参照 (Range オブジェクト) 16 #N/A などのエラー値 64 値の配列 例えば「1」を指定すると数値しか受け付けなくなります。
応用編
Typeの戻り値を「8」や「64」にしてセルを範囲指定することで配列のようなデータの持ち方が出来る様になります。
Typeを使うと情報をコントロールできるが少し足りない
パラメータ「Type」で「1」を指定します。これでテキストボックスには数値だけしか入力できません。
文字列が入力された際は「数値が正しくありません」というメッセージボックスが出るので実務で使えそうな気がします。
しかしテキストボックスが空欄でOKボタンを押下すると画像のようなメッセージボックスが表示されてしまいます。
「この数式には問題があります。・・・」と言われても何のことか分かりません。
処理としては理想的なメッセージボックスではないです。この件も含めて以下事例で対策していきます。
参考:InputBox関数
参考としてInputBox関数のドキュメントへのリンクを用意しておきます。
InputBox関数では戻り値空白とキャンセルボタンを押した時の処理が区別できません。(戻り値が同じである為)
IsNumeric関数
続いてIsNumeric関数です。指定した値が「数値」かどうかを判定する関数です。
構文
構文とパラメータを見ていきましょう。非常にシンプルですね。
使い方もシンプルです。関数名を書いてかっこの中に判定したいキーワードを入力するだけです。
戻り値
かっこの中のキーワードが全て数値だと認識された時は「True」が返ってきます。それ以外は「False」が返ってきます。
よって関数単体で使う事は出来ません。戻り値を受け取る変数と一緒に使いましょう。
事例を使って課題を解決させる
再度課題を見て状況を整理しておきましょう。
- テキストボックスが空白のままOKボタンを押される事がある(処理が用意できてない)
- 「数値で入力・・・」と書いていてもテキストボックスに文字列が入力されてしまう
以降作業環境、コード、解説の流れで説明していきます。課題を解決させます。
方向性としては「どんな値が入力されてもその後の処理でカバーする」という考え方でプロシージャを用意します。
作業環境
今回はInputBoxの検証ですので特定の作業環境は用意していません。(ワークシートには何の情報も無い状態です)
コードを実行するとただInputBoxが出てくるだけの環境です。コードをコピーしていただければすぐに試す事ができます。
事例として生まれた年(西暦)を入力してもらうInputBoxを用意しました。
表示されたInputbox内のテキストボックスの上には「数値のみを入力してほしい」旨の記載をしています。
私がコードを作成した段階では2000年生まれの人は 2000 と入力してほしいと思っています。
しかし注意書きを用意してもテキストボックスが空欄のままだったり文字列を入力する人は一定数居ます。
非常に残念ですが作り手はどんな例外処理が起きてもマクロが止まらない様に準備する必要があります。
コード
コードを紹介します。変数を1つ使用しています。主にInputBoxメソッドとIfステートメントで構成されています。
Sub テスト()
Dim y As Variant 'yearの「y」
y = Application.InputBox("生まれた年(西暦)を教えてください" _
& vbCrLf & vbCrLf & "「4桁の半角数値のみ」入力してください", "質問です")
If y = "" Then
MsgBox "テキストボックスが空欄のままOKボタンが押されました。" _
& vbCrLf & "操作をやり直してください。", vbExclamation, "お知らせ"
Exit Sub
ElseIf y = False Then
MsgBox "入力が中止されました。" _
& vbCrLf & "操作をやり直してください。", vbCritical, "お知らせ"
Exit Sub
Else
If IsNumeric(y) Then
MsgBox "生まれた年は" & Val(y) & "年です", vbInformation, "お知らせ"
Exit Sub
Else
MsgBox "半角数値以外の値が入力されています。" _
& vbCrLf & "操作をやり直してください。", vbQuestion, "お知らせ"
Exit Sub
End If
End If
End Sub
メッセージボックスに表示されるアイコンを4つの分岐と合わせて使い分けています。
アイコンの種類で見た目でも処理を認識出来る様な工夫をしています。
解説
まずはInputBoxメソッドです。値はVariant型の変数で受けます。よってどんな値でも受けることができます。
続いて条件分岐です。Variant型の変数に受け取った値を処理する為に条件分岐を使います。
分岐は4つ用意します。最終的に4つの分岐のどこかに処理が進む様にしています。
どの分岐にも作業者をサポートするようなメッセージボックスを用意しています。
それぞれはそんなに難しいものではないので安心してください。順番に説明していきます。
条件分岐やメッセージボックスについて知りたい方はこちらの記事をご覧ください。
条件分岐の中ではElseIfを使用しています。ElseIfを用いたIfステートメントはこちらの記事をご覧ください。
ElseIfの使い方【ElseIF&For】マクロ内で分岐とループを組み合わせる-3
1_テキストボックスが空白でOKボタンを押した時の処理
テキストボックスが空白(空欄)でOKボタンを押した時の戻り値は「ダブルクォーテーション2つ」です。
戻り値がダブルクォーテーション2つの時は「テキストボックスが空欄のまま・・・」というMsgBoxを用意します。
2_キャンセルボタンを押した時の処理
キャンセルボタンがクリック(押下)された時の戻り値は「False」です。
戻り値がFalseの時は「入力が中止されました。・・・」というMsgBoxを用意します。
3_数値が入力された時の処理
Ifステートメントの条件としてIsNumeric関数を使用します。
Trueが返ってきた時は全て数値です。「生まれた年は・・・」というMsgBoxを用意します。
ただし今回はIsNumeric関数と一緒に使うのでVal関数としては数字(文字列)を数値に変えるだけの処理になります。
4_文字列が入力された時の処理
3番の処理に連動しています。3番の処理でFalseが返ってきた時はテキストボックスに数値以外の値が入力されています。
「半角数値以外の値が入力されています。・・・」というMsgBoxを用意します。
まとめ
InputBox関数で対応出来なかった課題をInputBoxメソッドとIsNumeric関数を使って解決させることができました。
ポイントはもちろんInputBoxメソッドですが実はもう1つポイントがあります。InputBoxメソッドの値を受ける変数です。
Variant型を使う事でどんな値でも受けることができる様にしました。
InputBoxメソッドでは「とにかく値を受け取る」という仕様にしたかった為です。
「とにかく値を受け取る」という仕様は後々メンテナンスをする時にも少ない手数で対応する事ができます。
今回想定できなかった処理が出てきた際は条件分岐の条件と分岐を付け足すだけで対応出来る様になります。
ベストアンサーとまでは言えないのですが色々な面でメリットがあるプロシージャですので是非使ってみてください。
条件分岐に関連する記事を用意しておきます。条件分岐が理解出来ればどんな処理でも捌く事が出来るようになります。
条件分岐を理解する【エラーにならない】 VBA条件分岐完全ガイドコードのテンプレを紹介