【VBA】InputBoxで条件を入力させて処理を動的に変える方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

  • VBAのInputBoxで入力ダイアログを表示し、ユーザーの入力値を処理に使える
  • キャンセル判定を正しく書いて、意図しない処理の実行を防げる
  • 入力値のバリデーション(数値チェック、空欄チェック)ができる
  • Application.InputBoxで型を指定した入力(数値のみ、セル範囲選択)ができる
  • 実務版: InputBoxで部署名を入力→該当データを抽出して別シートにコピーできる

対象: Excel 2016以降 / Microsoft 365、Windows 10/11


完成イメージ(Before / After)

Before(コード書き換え):

  1. マクロの対象部署を変えたい
  2. VBEを開いてコード内の部署名を書き換える
  3. マクロを実行
  4. 別の部署に変えたいとき → またVBEを開いて書き換え
  5. 毎回この作業を繰り返す

After(InputBoxで動的入力):

  1. マクロを実行
  2. InputBoxが表示される →「営業部」と入力して「OK」
  3. 営業部のデータだけが別シートに抽出される
  4. 別の部署にしたいとき → もう一度実行して部署名を入力するだけ

月次レポートを作るマクロを書いたのに、対象部署を変えるたびにコードの文字列を書き換えていた。「営業部」を「総務部」に直すだけなのに、毎回VBEを開くのが面倒。InputBoxで入力させるようにしたら、コードを触らず誰でも使えるマクロになった。

MsgBoxは「メッセージを表示するだけ」の機能。InputBoxは「ユーザーに値を入力させる」機能。この違いを押さえるとマクロの幅が広がる。MsgBoxの使い方は MsgBoxの使い方 を参照。

InputBoxを使えば、マクロの条件をコード変更なしで動的に切り替えられる。


実行前の準備

バックアップを取る

実務版ではデータの抽出・コピー操作があるため、マクロ実行前にExcelファイルのコピーを別フォルダに保存しておく。

Excelをマクロ有効ブック(.xlsm)で保存する

拡張子が .xlsx のままだとマクロが保存できない。

  1. 「ファイル」→「名前を付けて保存」
  2. ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
  3. 保存

手順(コピペ → 実行まで約5分)

VBE(コードを書く画面)を開く

  1. Excelで Alt + F11 を押す
  2. VBE(Visual Basic Editor)が開く

標準モジュールを挿入する

  1. VBEのメニュー →「挿入」→「標準モジュール」
  2. 白い画面(コードウィンドウ)が表示される

コードを貼り付けて実行する

  1. コードウィンドウに、下のコードをそのままコピペする
  2. 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

書き換えポイント

変数・箇所 説明 初期値
"部署名を入力してください。" ダイアログに表示するメッセージ 部署名の入力を促す文
"部署名入力" ダイアログのタイトルバー 「部署名入力」
"営業部" 入力欄のデフォルト値。省略可 営業部

コードの流れ

  1. InputBox で入力ダイアログを表示(第1引数: メッセージ、第2引数: タイトル、第3引数: デフォルト値)
  2. ユーザーが値を入力して「OK」→ 入力値が inputVal に格納される
  3. ユーザーが「キャンセル」→ 空文字 "" が返る
  4. If inputVal = "" でキャンセル・空欄を判定して処理を中止
  5. 入力値を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のデフォルト値。不要なら "" に変更 営業部

コードの流れ

  1. InputBoxで入力: 部署名を入力させる。デフォルト値は「営業部」
  2. キャンセル判定: 空文字なら処理中止
  3. バリデーション: Trim で前後の空白を除去し、空欄チェック
  4. データ存在チェック: 最終行が2未満ならデータなしで終了
  5. 抽出先シート準備: 「抽出結果」シートが既存なら削除して新規作成
  6. ヘッダーコピー: 1行目のヘッダーを抽出先にコピー
  7. AutoFilter: A列を入力した部署名でフィルタ
  8. データコピー: フィルタされたデータを抽出先にコピー(0件チェック付き)
  9. AutoFilter解除: フィルタを解除して元データを元に戻す
  10. 完了メッセージ: 部署名と抽出件数を表示。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.InputBoxType:=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.InputBoxType:=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.InputBoxType:=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.InputBoxType:=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.InputBoxFalse 判定
  • 数値入力は Application.InputBoxType:=1、セル範囲選択は Type:=8
  • 入力値は Trim で空白除去、IsNumeric で数値チェックなどのバリデーションをかける

関連記事


次にやりたくなること

  • 入力フォームで手入力ミスを防ぐ方法: 複数の入力項目をまとめたフォームを作りたい場合。InputBoxは1項目ずつしか入力できないが、UserFormなら部署名・期間・金額をまとめて入力できる
  • 入力規則(ドロップダウンリスト)をVBAで一括設定: 選択肢が決まっている場合はドロップダウンリストで入力ミスを防ぐ。InputBoxの自由入力と使い分ける

もっとカスタマイズしたい場合

「入力フォームをもっと本格的に作りたい」「InputBoxの入力値に応じて複数シートを自動生成したい」「複数のInputBoxを連続で表示して条件を組み合わせたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。

相談時に伝えると話が早い情報:

  • Excel のバージョン / OS
  • InputBoxで入力させたい項目(部署名、期間、金額など)
  • 入力後にやりたい処理(抽出、集計、PDF出力など)
  • 使うのは自分だけか、チームメンバーも使うか

コメント

タイトルとURLをコピーしました