ExcelVBAでユーザーにセル範囲を選んでもらいたいとき、VBA標準のInputBox関数では文字列しか受け取れません。実はApplication.InputBoxメソッドを使えば、ユーザーがマウスでクリック&ドラッグしたセル範囲をそのままRangeオブジェクトとして受け取ることができます。
この記事では、Application.InputBoxのType:=8引数を使ってセル範囲を取得する方法を、基本の書き方からキャンセル時のエラー処理まで解説します。集計マクロや印刷範囲指定マクロなど、実務でそのまま使える形で紹介します。
Application.InputBoxとInputBox関数の違い
VBAには似た名前の機能が2つあります。
InputBox関数:文字列(テキスト)を入力させる。セル参照を渡してもテキストとして扱われるApplication.InputBoxメソッド:Type引数を指定することで、数値・文字列・セル範囲など、目的に応じた型で値を受け取れる
Type引数の主な値は次のとおりです。
| Type値 | 意味 |
|---|---|
| 0 | 数式 |
| 1 | 数値 |
| 2 | 文字列 |
| 4 | 論理値(True/False) |
| 8 | セル範囲(Rangeオブジェクト) |
| 64 | 配列 |
セル範囲を取得したい場合はType:=8を指定します。
基本の書き方
以下は、ユーザーにセル範囲を選択させて、その合計値をメッセージ表示する基本コードです。
Sub GetRangeFromUser()
Dim selectedRange As Range
On Error Resume Next
Set selectedRange = Application.InputBox( _
Prompt:="集計したいセル範囲を選択してください", _
Title:="範囲選択", _
Type:=8)
On Error GoTo 0
If selectedRange Is Nothing Then
MsgBox "範囲が選択されませんでした。処理を中止します。"
Exit Sub
End If
MsgBox "選択範囲の合計は " & Application.WorksheetFunction.Sum(selectedRange) & " です。"
End Sub
ポイントはType:=8を指定することです。これにより、ダイアログを開いたときにユーザーがセルをクリック・ドラッグして範囲を選択できるようになり、戻り値はRangeオブジェクトとして受け取れます。
キャンセル時のエラー処理が必須
Application.InputBoxは、ユーザーがキャンセルボタンを押すとFalse(Booleanの偽値)を返します。しかし戻り値をRange型の変数で受け取ろうとしているため、そのまま代入するとエラーが発生します。
このエラーを回避するために、On Error Resume Nextで一時的にエラーを無視し、代入後にselectedRange Is Nothingで判定するのが定番のパターンです。
On Error Resume Next
Set selectedRange = Application.InputBox(Prompt:="範囲を選択", Type:=8)
On Error GoTo 0
If selectedRange Is Nothing Then
Exit Sub
End If
On Error Resume Nextの直後は必ずOn Error GoTo 0でエラー処理を元に戻すことを忘れないようにしましょう。以降のコードで想定外のエラーが握りつぶされてしまうのを防げます。
既定の選択範囲を指定する
Default引数を使うと、ダイアログを開いた時点であらかじめ選択されているセル範囲を指定できます。ユーザーが今選んでいる範囲をそのまま初期値にしたい場合に便利です。
Sub GetRangeWithDefault()
Dim selectedRange As Range
On Error Resume Next
Set selectedRange = Application.InputBox( _
Prompt:="範囲を確認・修正してください", _
Default:=Selection.Address, _
Type:=8)
On Error GoTo 0
If selectedRange Is Nothing Then Exit Sub
selectedRange.Interior.Color = RGB(255, 255, 0)
End Sub
このコードでは、実行前に選択していたセル範囲がダイアログの初期値として表示され、ユーザーはそのまま確定するか範囲を選び直すことができます。確定後は選択範囲を黄色で塗りつぶします。
実践例:選択範囲だけを別シートにコピーする
印刷したい範囲や集計対象をユーザーに選んでもらい、別シートへ転記する実務向けのマクロです。
Sub CopySelectedRangeToNewSheet()
Dim srcRange As Range
Dim newSheet As Worksheet
On Error Resume Next
Set srcRange = Application.InputBox( _
Prompt:="コピー元のセル範囲を選択してください", _
Title:="範囲コピー", _
Type:=8)
On Error GoTo 0
If srcRange Is Nothing Then
MsgBox "処理をキャンセルしました。"
Exit Sub
End If
Set newSheet = Worksheets.Add(After:=Worksheets(Worksheets.Count))
srcRange.Copy Destination:=newSheet.Range("A1")
MsgBox "「" & newSheet.Name & "」シートにコピーしました。"
End Sub
srcRange.Copyで値だけでなく書式もそのままコピーされるため、集計表やレポートの雛形作成にも応用できます。
複数選択(離れたセル範囲)に対応する場合の注意点
Ctrlキーを押しながら離れた範囲を複数選択させたい場合は、Application.InputBoxではなくApplication.Unionと組み合わせる方法もありますが、Application.InputBox自体は単一のダイアログ操作の中で複数範囲選択にも対応しています(ユーザーがCtrlキーを押しながらドラッグした場合、Areasコレクションとして扱えます)。
Dim area As Range
For Each area In selectedRange.Areas
Debug.Print area.Address
Next area
複数範囲が選択される可能性がある処理では、For Each ... In selectedRange.Areasで1つずつ処理するようにしましょう。
まとめ
Application.InputBoxのType:=8を使うことで、ユーザーにマウス操作でセル範囲を選ばせ、そのままRangeオブジェクトとして受け取ることができます。通常のInputBox関数では実現できない機能なので、集計マクロや印刷範囲指定など、ユーザーに柔軟に範囲を選んでもらいたい場面ではぜひ活用してください。
キャンセル時にFalseが返る点だけは必ずOn Error Resume Next+Is Nothing判定でケアし、実行時エラーを防ぐようにしましょう。


コメント