Contents
この記事でできること
- VBAのInputBoxで入力ダイアログを表示し、ユーザーの入力値を処理に使える
- キャンセル判定を正しく書いて、意図しない処理の実行を防げる
- 入力値のバリデーション(数値チェック、空欄チェック)ができる
- Application.InputBoxで型を指定した入力(数値のみ、セル範囲選択)ができる
- 実務版: InputBoxで部署名を入力→該当データを抽出して別シートにコピーできる
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(コード書き換え):
- マクロの対象部署を変えたい
- VBEを開いてコード内の部署名を書き換える
- マクロを実行
- 別の部署に変えたいとき → またVBEを開いて書き換え
- 毎回この作業を繰り返す
After(InputBoxで動的入力):
- マクロを実行
- InputBoxが表示される →「営業部」と入力して「OK」
- 営業部のデータだけが別シートに抽出される
- 別の部署にしたいとき → もう一度実行して部署名を入力するだけ
月次レポートを作るマクロを書いたのに、対象部署を変えるたびにコードの文字列を書き換えていた。「営業部」を「総務部」に直すだけなのに、毎回VBEを開くのが面倒。InputBoxで入力させるようにしたら、コードを触らず誰でも使えるマクロになった。
MsgBoxは「メッセージを表示するだけ」の機能。InputBoxは「ユーザーに値を入力させる」機能。この違いを押さえるとマクロの幅が広がる。MsgBoxの使い方は MsgBoxの使い方 を参照。
InputBoxを使えば、マクロの条件をコード変更なしで動的に切り替えられる。
実行前の準備
バックアップを取る
実務版ではデータの抽出・コピー操作があるため、マクロ実行前にExcelファイルのコピーを別フォルダに保存しておく。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。
コード(最小版)– InputBoxで入力した値をメッセージ表示
まずはInputBoxの基本。入力ダイアログを表示して、入力された値をMsgBoxで表示するだけの最小コード。キャンセル判定も入れている。
'============================================================
' ■ InputBoxで値を入力してメッセージ表示(最小版)
' → 入力ダイアログを表示し、入力値をMsgBoxで確認
'============================================================
Sub InputBoxで値を入力する()
Dim inputVal As String
'--- InputBoxで入力ダイアログを表示
inputVal = InputBox("部署名を入力してください。", "部署名入力", "営業部")
'--- キャンセル判定(キャンセル or 空欄 → 終了)
If inputVal = "" Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
'--- 入力値を表示
MsgBox "入力された部署名: " & inputVal, vbInformation
End Sub
書き換えポイント
| 変数・箇所 | 説明 | 初期値 |
|---|---|---|
"部署名を入力してください。" |
ダイアログに表示するメッセージ | 部署名の入力を促す文 |
"部署名入力" |
ダイアログのタイトルバー | 「部署名入力」 |
"営業部" |
入力欄のデフォルト値。省略可 | 営業部 |
コードの流れ
InputBoxで入力ダイアログを表示(第1引数: メッセージ、第2引数: タイトル、第3引数: デフォルト値)- ユーザーが値を入力して「OK」→ 入力値が
inputValに格納される - ユーザーが「キャンセル」→ 空文字
""が返る If inputVal = ""でキャンセル・空欄を判定して処理を中止- 入力値をMsgBoxで表示
VBA標準の
InputBox関数は、キャンセルを押すと空文字""を返す。空欄で「OK」を押した場合も空文字。両者の区別が必要な場合はStrPtrを使うか、後述のApplication.InputBoxを使う。
コード(実務版)– InputBoxで部署名を入力→該当データを抽出して別シートにコピー
実務では「入力した値を条件にしてデータを処理する」パターンが多い。この実務版では、InputBoxで部署名を入力し、該当するデータをAutoFilterで抽出して「抽出結果」シートにコピーする。
自分はこのコードを月次レポートの部署別抽出に使っている。「営業部」と入力すれば営業部のデータだけが別シートにまとまる。部署を変えるときもコードを触らずInputBoxで入力するだけ。チームメンバーにも「部署名を入れるだけで使える」と好評だった。
AutoFilterでのデータ抽出の詳細は 複数条件でデータを抽出して別シートにまとめる を参照。エラー処理の詳細は エラー処理の基本 を参照。
マクロ実行中にエラーが発生すると、
ScreenUpdating = Falseのまま画面更新が停止した状態になることがある。その場合はVBEの「イミディエイトウィンドウ」でApplication.ScreenUpdating = Trueを実行すれば復帰する。
'============================================================
' ■ InputBoxで部署名を入力→該当データを抽出して別シートにコピー(実務版)
' → 「データ」シートのA列(部署)をInputBoxの入力値でフィルタ
' → 該当データを「抽出結果」シートにコピー
'============================================================
Sub 部署別データを抽出する()
Dim wsSrc As Worksheet
Dim wsDst As Worksheet
Dim lastRow As Long
Dim inputDept As String
Dim dstName As String
Dim filteredCount As Long
'--- InputBoxで部署名を入力
inputDept = InputBox("抽出したい部署名を入力してください。" & vbCrLf & _
"(例: 営業部、総務部、経理部)", _
"部署名入力", "営業部")
'--- キャンセル判定
If inputDept = "" Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
'--- 入力値のバリデーション(空白のみの入力を除外)
inputDept = Trim(inputDept)
If Len(inputDept) = 0 Then
MsgBox "部署名が入力されていません。", vbExclamation
Exit Sub
End If
'--- 元データのシートを取得
Set wsSrc = ThisWorkbook.Sheets("データ")
lastRow = wsSrc.Cells(wsSrc.Rows.Count, 1).End(xlUp).Row
'--- データがない場合は終了
If lastRow < 2 Then
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
'--- 画面更新を停止(高速化)
Application.ScreenUpdating = False
'--- 抽出先シートの準備(既存なら削除して再作成)
dstName = "抽出結果"
On Error Resume Next
Set wsDst = ThisWorkbook.Sheets(dstName)
On Error GoTo 0
If Not wsDst Is Nothing Then
Application.DisplayAlerts = False
wsDst.Delete
Application.DisplayAlerts = True
Set wsDst = Nothing
End If
Set wsDst = ThisWorkbook.Sheets.Add(After:=ThisWorkbook.Sheets(ThisWorkbook.Sheets.Count))
wsDst.Name = dstName
'--- ヘッダーをコピー
wsSrc.Rows(1).Copy Destination:=wsDst.Rows(1)
'--- AutoFilterで部署名を抽出
If wsSrc.AutoFilterMode Then wsSrc.AutoFilterMode = False
wsSrc.Range("A1:D" & lastRow).AutoFilter Field:=1, Criteria1:=inputDept
'--- 抽出結果をコピー(該当データが0件の場合はエラーになるため On Error で対応)
On Error Resume Next
filteredCount = wsSrc.Range("A2:A" & lastRow).SpecialCells(xlCellTypeVisible).Count
On Error GoTo 0
If filteredCount > 0 Then
wsSrc.Range("A2:D" & lastRow).SpecialCells(xlCellTypeVisible).Copy _
Destination:=wsDst.Range("A2")
End If
'--- AutoFilterを解除
wsSrc.AutoFilterMode = False
'--- 列幅を自動調整
wsDst.Columns("A:D").AutoFit
'--- 画面更新を再開
Application.ScreenUpdating = True
'--- 抽出結果シートを表示
wsDst.Activate
'--- 完了メッセージ
If filteredCount > 0 Then
MsgBox "「" & inputDept & "」のデータを抽出しました。" & vbCrLf & _
"抽出件数: " & filteredCount & " 件", vbInformation
Else
MsgBox "「" & inputDept & "」に該当するデータがありませんでした。", vbExclamation
End If
End Sub
書き換えポイント
| 変数・箇所 | 説明 | 初期値 |
|---|---|---|
Sheets("データ") |
元データがあるシート名 | 「データ」 |
"抽出結果" |
抽出先のシート名 | 「抽出結果」 |
Field:=1 |
フィルタ対象の列番号(1=A列、2=B列…) | 1(A列:部署) |
Range("A1:D" & lastRow) |
データの範囲。列数に応じて変更 | A〜D列 |
"営業部" |
InputBoxのデフォルト値。不要なら "" に変更 |
営業部 |
コードの流れ
- InputBoxで入力: 部署名を入力させる。デフォルト値は「営業部」
- キャンセル判定: 空文字なら処理中止
- バリデーション:
Trimで前後の空白を除去し、空欄チェック - データ存在チェック: 最終行が2未満ならデータなしで終了
- 抽出先シート準備: 「抽出結果」シートが既存なら削除して新規作成
- ヘッダーコピー: 1行目のヘッダーを抽出先にコピー
- AutoFilter: A列を入力した部署名でフィルタ
- データコピー: フィルタされたデータを抽出先にコピー(0件チェック付き)
- AutoFilter解除: フィルタを解除して元データを元に戻す
- 完了メッセージ: 部署名と抽出件数を表示。0件の場合は「該当データなし」と表示
SpecialCells(xlCellTypeVisible)はフィルタで表示されているセルだけを取得する。フィルタ結果が0件の場合はエラーになるため、On Error Resume Nextで囲んでfilteredCountを安全に取得している。
応用:Application.InputBoxで型を指定して入力させる
VBA標準の InputBox 関数は戻り値が常に文字列。数値やセル範囲を入力させたい場合は Application.InputBox メソッドを使う。Type 引数で入力の型を指定できる。
数値のみ入力させる(Type:=1)
'============================================================
' ■ Application.InputBoxで数値のみ入力させる
' → 数値以外を入力すると再入力を促される
'============================================================
Sub 数値を入力させる()
Dim inputVal As Variant
'--- Application.InputBoxで数値入力(Type:=1)
inputVal = Application.InputBox("抽出する金額の下限を入力してください。", _
"金額入力", 10000, Type:=1)
'--- キャンセル判定(Application.InputBoxはFalseを返す)
If inputVal = False Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
MsgBox "入力された金額: " & Format(inputVal, "#,##0") & " 円", vbInformation
End Sub
セル範囲を選択させる(Type:=8)
選択肢が決まっている場合はドロップダウンリストのほうが向いている。詳しくは 入力規則(ドロップダウンリスト)をVBAで一括設定 を参照。
'============================================================
' ■ Application.InputBoxでセル範囲を選択させる
' → ユーザーがセルをクリック/ドラッグで範囲を選択
'============================================================
Sub セル範囲を選択させる()
Dim rng As Range
'--- Application.InputBoxでセル範囲選択(Type:=8)
On Error Resume Next
Set rng = Application.InputBox("処理対象のセル範囲を選択してください。", _
"範囲選択", Type:=8)
On Error GoTo 0
'--- キャンセル判定(Nothingなら中止)
If rng Is Nothing Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
MsgBox "選択された範囲: " & rng.Address & vbCrLf & _
"セル数: " & rng.Cells.Count, vbInformation
End Sub
Type引数の主な値
| Type値 | 入力の型 | 用途 |
|---|---|---|
| 1 | 数値 | 金額、件数、行番号など |
| 2 | 文字列 | 部署名、ファイル名など |
| 8 | セル範囲 | 処理対象のセル範囲を選択 |
Application.InputBoxでType:=8(セル範囲)を使う場合、キャンセルするとエラーが発生する。On Error Resume Nextで囲んでrng Is Nothingで判定する。
よくある落とし穴5選
| # | 落とし穴 | 原因 | 対策 |
|---|---|---|---|
| 1 | キャンセルを押したのに処理が走る | キャンセル判定を書いていない。空文字のまま後続処理が実行される | InputBoxの直後に If inputVal = "" でキャンセル判定を必ず入れる |
| 2 | InputBox関数とApplication.InputBoxのキャンセル判定を混同 | InputBox関数は空文字 "" を返す。Application.InputBoxは False を返す。判定方法が異なる |
使っているのが関数かメソッドかを確認し、対応する判定を書く |
| 3 | 数値を入力したのに文字列として扱われる | VBA標準のInputBox関数は戻り値が常に文字列型。"100" と 100 は異なる |
数値として使うなら CLng(inputVal) や CDbl(inputVal) で変換する。または Application.InputBox の Type:=1 を使う |
| 4 | Application.InputBox(Type:=8)でキャンセルするとエラーになる | Type:=8のキャンセル時はエラーが発生する。通常の = False 判定では捕捉できない |
On Error Resume Next で囲み、rng Is Nothing で判定する |
| 5 | 入力値に前後の空白が含まれていて一致しない | ユーザーが「 営業部 」のように前後に空白を入れて入力すると、完全一致で検索したときにヒットしない | Trim(inputVal) で前後の空白を除去してから使う |
自分もキャンセル判定を書かずにやらかしたことがある。InputBoxでキャンセルを押したのに処理が走ってしまい、空文字のまま抽出処理が実行されて全データがコピーされた。それ以来、InputBoxの直後には必ずキャンセル判定を入れるようにしている。
FAQ
Q1: InputBoxで数値だけ入力させたい
Application.InputBox に Type:=1 を指定する。文字列を入力するとExcelが「入力した数式は正しくありません」と自動で再入力を促してくれる。
Dim inputVal As Variant
inputVal = Application.InputBox("数値を入力", Type:=1)
If inputVal = False Then Exit Sub ' キャンセル
Q2: InputBoxにデフォルト値を設定したい
第3引数 Default に値を指定する。ダイアログを開いたときに入力欄にデフォルト値が入った状態になる。
' デフォルト値に「営業部」を設定
inputVal = InputBox("部署名を入力", "部署名入力", "営業部")
Q3: キャンセルと空欄で「OK」を押した場合を区別したい
VBA標準の InputBox 関数では、キャンセルも空欄OKもどちらも空文字 "" が返る。区別したい場合は StrPtr を使う。
Dim inputVal As String
inputVal = InputBox("値を入力してください")
If StrPtr(inputVal) = 0 Then
MsgBox "キャンセルが押されました"
ElseIf inputVal = "" Then
MsgBox "空欄でOKが押されました"
Else
MsgBox "入力値: " & inputVal
End If
Q4: InputBoxでセル範囲を選択させたい
Application.InputBox に Type:=8 を指定する。ユーザーがシート上のセルをクリック/ドラッグして範囲を選択できる。
Dim rng As Range
On Error Resume Next
Set rng = Application.InputBox("範囲を選択", Type:=8)
On Error GoTo 0
If rng Is Nothing Then Exit Sub ' キャンセル
Q5: InputBoxの代わりにもっと本格的な入力フォームを作りたい
InputBoxは1つの値しか入力できない。複数の入力項目(部署名・期間・金額など)をまとめて入力させたい場合は、UserFormのほうが適している。入力フォームで手入力ミスを防ぐ方法 を参照。
まとめ
InputBox関数で入力ダイアログを表示し、ユーザーの入力値を処理条件に使える- キャンセル判定は必須。
InputBox関数は""判定、Application.InputBoxはFalse判定 - 数値入力は
Application.InputBoxのType:=1、セル範囲選択はType:=8 - 入力値は
Trimで空白除去、IsNumericで数値チェックなどのバリデーションをかける
関連記事
- 入力フォームで手入力ミスを防ぐ方法 — InputBoxでは足りない場合のステップアップ先
- MsgBoxの使い方 — 入力ではなく通知・確認だけで済む場合はMsgBox
次にやりたくなること
- 入力フォームで手入力ミスを防ぐ方法: 複数の入力項目をまとめたフォームを作りたい場合。InputBoxは1項目ずつしか入力できないが、UserFormなら部署名・期間・金額をまとめて入力できる
- 入力規則(ドロップダウンリスト)をVBAで一括設定: 選択肢が決まっている場合はドロップダウンリストで入力ミスを防ぐ。InputBoxの自由入力と使い分ける
もっとカスタマイズしたい場合
「入力フォームをもっと本格的に作りたい」「InputBoxの入力値に応じて複数シートを自動生成したい」「複数のInputBoxを連続で表示して条件を組み合わせたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- InputBoxで入力させたい項目(部署名、期間、金額など)
- 入力後にやりたい処理(抽出、集計、PDF出力など)
- 使うのは自分だけか、チームメンバーも使うか


コメント