Contents
この記事でできること
- VBAのApplication.FileDialogでファイル選択ダイアログを表示し、ユーザーにファイルを選ばせる
- .Filters.Addで拡張子フィルタを設定し、Excelファイルだけを表示させる
- .AllowMultiSelectで複数ファイルの同時選択ができる
- .InitialFileNameで初期フォルダを指定できる
- .Showの戻り値でキャンセル判定を正しく書ける
- 実務版: ダイアログでExcelファイルを選択→開いて集計→結果をシートに書き出す
対象: Excel 2016以降 / Microsoft 365、Windows 10/11
完成イメージ(Before / After)
Before(パス直書き):
- マクロの対象ファイルを変えたい
- VBEを開いてコード内のファイルパスを書き換える
- マクロを実行
- 別のファイルに変えたいとき → またVBEを開いて書き換え
- 毎回この作業を繰り返す
After(ファイル選択ダイアログ):
- マクロを実行
- ファイル選択ダイアログが表示される → 対象ファイルをクリックして「開く」
- 選択したファイルのデータが集計される
- 別のファイルにしたいとき → もう一度実行してファイルを選ぶだけ
フォルダ内のExcelファイルを集計するマクロを作ったが、ファイルパスをコードに直書きしていた。対象ファイルが変わるたびにVBEを開いてパスを修正するのが正直めんどくさかった。ファイル選択ダイアログを組み込んだら、コードを触らず誰でも対象ファイルを選べるマクロになった。同じ面倒を感じている人がこの記事でサクッと解消できればうれしい。
UserFormは複数の入力項目をまとめた本格的なフォーム向き。FileDialogはファイルやフォルダの選択に特化している。用途に応じて使い分けるとよい。UserFormの使い方は 入力フォームで手入力ミスを防ぐ方法 を参照。
ファイル選択ダイアログを使えば、対象ファイルをコード変更なしでユーザーが自由に選べる。
実行前の準備
バックアップを取る
実務版ではファイルを開いてデータを集計するため、マクロ実行前にExcelファイルのコピーを別フォルダに保存しておく。
Excelをマクロ有効ブック(.xlsm)で保存する
拡張子が .xlsx のままだとマクロが保存できない。
- 「ファイル」→「名前を付けて保存」
- ファイルの種類を「Excelマクロ有効ブック (*.xlsm)」に変更
- 保存
手順(コピペ → 実行まで約5分)
VBE(コードを書く画面)を開く
- Excelで
Alt + F11を押す - VBE(Visual Basic Editor)が開く
標準モジュールを挿入する
- VBEのメニュー →「挿入」→「標準モジュール」
- 白い画面(コードウィンドウ)が表示される
コードを貼り付けて実行する
- コードウィンドウに、下のコードをそのままコピペする
Alt + F8→ マクロ名を選んで「実行」
ボタンに割り当てれば毎回Alt+F8を押さなくて済む。方法は マクロをボタン1つで実行する方法 を参照。
コード(最小版)– ファイル選択ダイアログでファイルパスを取得
まずはFileDialogの基本。ファイル選択ダイアログを表示して、選択されたファイルのパスをMsgBoxで表示するだけの最小コード。キャンセル判定も入れている。
'============================================================
' ■ ファイル選択ダイアログでパスを取得(最小版)
' → ダイアログを表示し、選択したファイルのパスをMsgBoxで確認
'============================================================
Sub ファイル選択ダイアログを表示する()
Dim fd As FileDialog
Dim selectedFile As String
'--- FileDialogオブジェクトを取得(ファイル選択モード)
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'--- ダイアログの設定
With fd
.Title = "対象ファイルを選択してください" ' タイトル
.AllowMultiSelect = False ' 単一選択
.InitialFileName = "C:\" ' 初期フォルダ
'--- フィルタの設定(Excelファイルのみ表示)
.Filters.Clear
.Filters.Add "Excelファイル", "*.xlsx; *.xlsm; *.xls"
.Filters.Add "すべてのファイル", "*.*"
End With
'--- ダイアログを表示(-1: OK、0: キャンセル)
If fd.Show = -1 Then
selectedFile = fd.SelectedItems(1)
MsgBox "選択されたファイル: " & selectedFile, vbInformation
Else
MsgBox "キャンセルされました。", vbExclamation
End If
End Sub
書き換えポイント
| 変数・箇所 | 説明 | 初期値 |
|---|---|---|
"対象ファイルを選択してください" |
ダイアログのタイトルバーに表示する文字 | 「対象ファイルを選択してください」 |
"C:\" |
ダイアログを開いたときの初期フォルダ。ThisWorkbook.Path にすれば自ブックと同じフォルダになる |
C:\ |
"*.xlsx; *.xlsm; *.xls" |
表示するファイルの拡張子。; で区切って複数指定可 |
Excel系ファイル |
.AllowMultiSelect = False |
True にすると複数ファイルを選択可能 |
False(単一選択) |
コードの流れ
Application.FileDialog(msoFileDialogFilePicker)でファイル選択ダイアログのオブジェクトを取得.Titleでタイトル、.InitialFileNameで初期フォルダ、.Filters.Addでフィルタを設定.Filters.Clearで既存のフィルタをクリアしてから.Filters.Addで追加(クリアしないと前回の設定が残る).Showでダイアログを表示。ユーザーがファイルを選んで「開く」→ 戻り値-1。「キャンセル」→ 戻り値0.SelectedItems(1)で選択されたファイルのフルパスを取得(インデックスは1始まり)- MsgBoxでパスを表示
.Showの戻り値は-1(True相当)と0(False相当)。If fd.Show = -1 ThenまたはIf fd.Show <> 0 Thenで判定する。If fd.Show Thenと書くと-1がTrueと評価されるため動作するが、明示的に-1と比較するほうが可読性が高い。
コード(実務版)– ダイアログでExcelファイルを選択→開いて集計→結果を書き出す
実務では「ダイアログでファイルを選ばせて、そのファイルを開いて処理する」パターンが多い。この実務版では、ファイル選択ダイアログでExcelファイルを選択し、開いてA列のデータ合計を集計して結果をシートに書き出す。
自分はこのコードを月次の売上報告集計に使っている。毎月届くExcelファイルをダイアログで選ぶだけで、A列の売上合計が集計シートに書き出される。ファイル名が毎月変わっても、コードを触る必要がない。
ファイルを開いて処理する詳細は Excelファイルを自動で開いて処理して閉じる方法 を参照。ファイルの存在チェックは ファイルやフォルダの存在を確認してから処理する方法 を参照。エラー処理の詳細は エラー処理の基本 を参照。
'============================================================
' ■ ダイアログでExcelファイルを選択→開いて集計→結果を書き出す(実務版)
' → ファイル選択ダイアログでExcelファイルを選択
' → 選択したファイルを読み取り専用で開く
' → A列(2行目以降)の合計を計算
' → 集計結果を「Sheet1」に書き出す
'============================================================
Sub ダイアログで選んだファイルを集計する()
Dim fd As FileDialog
Dim selectedFile As String
Dim wb As Workbook
Dim wsSrc As Worksheet
Dim wsResult As Worksheet
Dim lastRow As Long
Dim total As Double
'--- FileDialogオブジェクトを取得(ファイル選択モード)
Set fd = Application.FileDialog(msoFileDialogFilePicker)
'--- ダイアログの設定
With fd
.Title = "集計対象のExcelファイルを選択してください"
.AllowMultiSelect = False
.InitialFileName = ThisWorkbook.Path & "\"
'--- フィルタの設定(Excelファイルのみ)
.Filters.Clear
.Filters.Add "Excelファイル", "*.xlsx; *.xlsm; *.xls"
End With
'--- ダイアログを表示
If fd.Show <> -1 Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
'--- 選択されたファイルパスを取得
selectedFile = fd.SelectedItems(1)
'--- 画面更新を停止(高速化)
Application.ScreenUpdating = False
'--- エラー発生時もScreenUpdatingを復帰させる
On Error GoTo ErrHandler
'--- 選択したファイルを読み取り専用で開く
Set wb = Workbooks.Open(selectedFile, ReadOnly:=True, UpdateLinks:=0)
Set wsSrc = wb.Sheets(1)
'--- A列の最終行を取得
lastRow = wsSrc.Cells(wsSrc.Rows.Count, 1).End(xlUp).Row
'--- データがない場合は終了
If lastRow < 2 Then
wb.Close SaveChanges:=False
Application.ScreenUpdating = True
MsgBox "データがありません。", vbExclamation
Exit Sub
End If
'--- A列(2行目以降)の合計を計算
' ※ 文字列が混在していてもエラーにならないよう安全に処理
On Error Resume Next
total = Application.WorksheetFunction.Sum(wsSrc.Range("A2:A" & lastRow))
If Err.Number <> 0 Then
total = 0
Err.Clear
End If
On Error GoTo ErrHandler
'--- ファイルを閉じる(保存しない)
wb.Close SaveChanges:=False
Set wb = Nothing
'--- 集計結果をSheet1に書き出す
Set wsResult = ThisWorkbook.Sheets("Sheet1")
Dim writeRow As Long
writeRow = wsResult.Cells(wsResult.Rows.Count, 1).End(xlUp).Row + 1
wsResult.Cells(writeRow, 1).Value = Dir(selectedFile) ' ファイル名
wsResult.Cells(writeRow, 2).Value = total ' 合計値
wsResult.Cells(writeRow, 3).Value = Now ' 集計日時
'--- 列幅を自動調整
wsResult.Columns("A:C").AutoFit
'--- 画面更新を再開
Application.ScreenUpdating = True
'--- 完了メッセージ
MsgBox "集計が完了しました。" & vbCrLf & _
"ファイル: " & Dir(selectedFile) & vbCrLf & _
"A列合計: " & Format(total, "#,##0"), vbInformation
Exit Sub
ErrHandler:
'--- エラー発生時も画面更新を必ず復帰
Application.ScreenUpdating = True
If Not wb Is Nothing Then
wb.Close SaveChanges:=False
Set wb = Nothing
End If
MsgBox "エラーが発生しました: " & Err.Description, vbCritical
End Sub
書き換えポイント
| 変数・箇所 | 説明 | 初期値 |
|---|---|---|
"集計対象のExcelファイルを選択してください" |
ダイアログのタイトル | 集計対象の選択を促す文 |
ThisWorkbook.Path & "\" |
初期フォルダ。自ブックと同じフォルダを起点にする | 自ブックのフォルダ |
"*.xlsx; *.xlsm; *.xls" |
表示するファイルの拡張子 | Excel系ファイル |
wsSrc.Range("A2:A" & lastRow) |
合計を計算する範囲。列や開始行に応じて変更 | A列の2行目以降 |
Sheets("Sheet1") |
集計結果を書き出すシート名 | Sheet1 |
コードの流れ
- ダイアログ表示: FileDialogでExcelファイルのみ表示するフィルタを設定し、ダイアログを表示
- キャンセル判定:
.Show <> -1ならキャンセルで終了 - ファイルを開く: 選択したファイルを
ReadOnly:=Trueで読み取り専用で開く - データ存在チェック: A列の最終行が2未満ならデータなしで終了
- 合計計算:
WorksheetFunction.SumでA列の2行目以降の合計を計算。文字列が混在していてもエラーにならないようOn Error Resume Nextで保護 - ファイルを閉じる:
SaveChanges:=Falseで保存せず閉じる - 結果書き出し: Sheet1にファイル名・合計値・集計日時を書き出す
- 完了メッセージ: ファイル名と合計値を表示
Dir(selectedFile)はフルパスからファイル名だけを取得する。"C:\Data\売上.xlsx"→"売上.xlsx"になる。
応用:フォルダ選択ダイアログ / 複数ファイル選択 / GetOpenFilenameとの違い
フォルダ選択ダイアログ(msoFileDialogFolderPicker)
ファイルではなくフォルダを選択させたい場合は msoFileDialogFolderPicker を使う。フォルダ内のファイルを一括処理するときに便利。複数ファイルの統合については 複数Excelファイルを1つに統合する方法 を参照。
'============================================================
' ■ フォルダ選択ダイアログ
' → ユーザーにフォルダを選択させてパスを取得
'============================================================
Sub フォルダ選択ダイアログを表示する()
Dim fd As FileDialog
Dim folderPath As String
'--- FileDialogオブジェクトを取得(フォルダ選択モード)
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
With fd
.Title = "対象フォルダを選択してください"
.InitialFileName = "C:\"
End With
'--- ダイアログを表示
If fd.Show = -1 Then
'--- 戻り値には末尾に \ が付かないため、手動で付ける
folderPath = fd.SelectedItems(1) & "\"
MsgBox "選択されたフォルダ: " & folderPath, vbInformation
Else
MsgBox "キャンセルされました。", vbExclamation
End If
End Sub
msoFileDialogFolderPickerの戻り値(SelectedItems(1))には末尾に\が付かない。Dirでファイルを列挙するときはfolderPath & "*.xlsx"のように\が必要なので、取得直後に& "\"を付けておくのが確実。
複数ファイル選択(AllowMultiSelect = True)
'============================================================
' ■ 複数ファイル選択ダイアログ
' → 複数ファイルを選択してパスを一覧表示
'============================================================
Sub 複数ファイルを選択する()
Dim fd As FileDialog
Dim i As Long
Dim msg As String
Set fd = Application.FileDialog(msoFileDialogFilePicker)
With fd
.Title = "処理対象のファイルを選択してください(複数選択可)"
.AllowMultiSelect = True
.InitialFileName = ThisWorkbook.Path & "\"
.Filters.Clear
.Filters.Add "Excelファイル", "*.xlsx; *.xlsm"
End With
If fd.Show <> -1 Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
'--- 選択されたファイルを順に処理
msg = "選択されたファイル(" & fd.SelectedItems.Count & "件):" & vbCrLf
For i = 1 To fd.SelectedItems.Count
msg = msg & i & ". " & fd.SelectedItems(i) & vbCrLf
Next i
MsgBox msg, vbInformation
End Sub
.AllowMultiSelect = Trueにすると、CtrlキーやShiftキーで複数ファイルを選択できる。.SelectedItems.Countで選択数を取得し、For i = 1 To .SelectedItems.Countでループ処理する。インデックスは 1始まり なので注意。
Application.GetOpenFilename との使い分け
| 項目 | FileDialog | GetOpenFilename |
|---|---|---|
| フィルタ設定 | .Filters.Add で柔軟に設定 |
引数で文字列指定 |
| 初期フォルダ | .InitialFileName で指定可能 |
直接指定不可(ChDir で間接的に変更は可能だが、FileDialogのほうが直感的) |
| フォルダ選択 | FolderPickerで可能 | 不可 |
| ダイアログタイトル | .Title で設定 |
Title 引数で設定 |
| 戻り値 | SelectedItemsコレクション | ファイルパス文字列(Variant) |
| コードの簡潔さ | やや長い | シンプル |
GetOpenFilenameのほうがコードが短いが、初期フォルダの指定やフォルダ選択ができない。実務で細かく制御したい場合はFileDialogを使う。
' --- GetOpenFilenameのシンプルな例 ---
Sub GetOpenFilenameの例()
Dim filePath As Variant
filePath = Application.GetOpenFilename("Excelファイル,*.xlsx")
If filePath = False Then
MsgBox "キャンセルされました。", vbExclamation
Exit Sub
End If
MsgBox "選択されたファイル: " & filePath, vbInformation
End Sub
よくある落とし穴5選
| # | 落とし穴 | 原因 | 対策 |
|---|---|---|---|
| 1 | キャンセルしたら「実行時エラー5」が出る | .Show の戻り値を確認せずに .SelectedItems(1) を参照している |
.Show = -1 を必ず確認してからSelectedItemsを参照する |
| 2 | 前回のフィルタ設定が残っている | .Filters.Clear を呼ばずに .Filters.Add だけ実行した |
.Filters.Add の前に必ず .Filters.Clear を入れる |
| 3 | ダイアログが毎回違うフォルダで開く | .InitialFileName を設定していない。直前に開いたフォルダが使われる |
.InitialFileName = ThisWorkbook.Path & "\" で初期フォルダを明示的に指定する |
| 4 | 複数選択でSelectedItems(0)を参照してエラーになる | VBAのSelectedItemsコレクションはインデックスが1始まり。0を指定するとエラー | For i = 1 To fd.SelectedItems.Count で1から開始する |
| 5 | InitialFileNameにフォルダを指定したのにファイル名入力欄に文字が入る | フォルダパスの末尾に \ を付けていない。"C:\Data" だとDataがファイル名として扱われる |
フォルダパスの末尾に必ず \ を付ける(例: "C:\Data\" ) |
自分も .Show の戻り値チェックを入れずにSelectedItems(1)を参照したことがある。キャンセルを押した瞬間に「実行時エラー5」で落ちて、そのたびにVBEのデバッグ画面が開いた。それ以来、.Showの直後に必ずキャンセル判定を入れるようにしている。
FAQ
Q1: ダイアログの初期フォルダを指定したい
.InitialFileName にフォルダパスを指定する。末尾に \ を付けるのがポイント。付けないとフォルダ名がファイル名入力欄に入ってしまう。
fd.InitialFileName = "C:\Data\売上報告\"
' 自ブックと同じフォルダにしたい場合
fd.InitialFileName = ThisWorkbook.Path & "\"
Q2: Excelファイルだけ表示するようにフィルタしたい
.Filters.Clear でクリアしてから .Filters.Add で追加する。複数の拡張子はセミコロン ; で区切る。
With fd
.Filters.Clear
.Filters.Add "Excelファイル", "*.xlsx; *.xlsm; *.xls"
.Filters.Add "CSVファイル", "*.csv"
.Filters.Add "すべてのファイル", "*.*"
End With
Q3: 複数ファイルをまとめて選択して順に処理したい
.AllowMultiSelect = True にして、SelectedItems をForループで回す。
fd.AllowMultiSelect = True
If fd.Show = -1 Then
Dim i As Long
For i = 1 To fd.SelectedItems.Count
Debug.Print fd.SelectedItems(i) ' 各ファイルのパス
Next i
End If
Q4: FileDialogとGetOpenFilenameのどちらを使うべきか
シンプルにファイルパスだけ取得したい場合: Application.GetOpenFilename が手軽。コードが短くて済む。
フィルタ・初期フォルダ・複数選択を細かく制御したい場合: Application.FileDialog のほうが柔軟。実務で使うならFileDialogを推奨。
Q5: フォルダを選択させてフォルダ内のファイルを一括処理したい
Application.FileDialog(msoFileDialogFolderPicker) でフォルダを選択させ、Dir でファイルを列挙する。
Dim fd As FileDialog
Set fd = Application.FileDialog(msoFileDialogFolderPicker)
If fd.Show = -1 Then
Dim folderPath As String
'--- 戻り値に末尾 \ が付かないため手動で付ける
folderPath = fd.SelectedItems(1) & "\"
Dim f As String
f = Dir(folderPath & "*.xlsx")
Do While f <> ""
Debug.Print folderPath & f
f = Dir()
Loop
End If
まとめ
Application.FileDialog(msoFileDialogFilePicker)でファイル選択ダイアログを表示できる.Filters.Clear→.Filters.Addで拡張子フィルタを設定する(Clearを忘れない).AllowMultiSelect = Trueで複数ファイルの同時選択が可能.InitialFileNameで初期フォルダを指定する(末尾に\を付ける).Showの戻り値で必ずキャンセル判定を行う(-1: OK、0: キャンセル)- フォルダ選択は
msoFileDialogFolderPickerを使う
関連記事
- 入力フォームで手入力ミスを防ぐ方法 — FileDialogではなくUserFormで本格的な入力画面を作りたい場合
- InputBoxで条件を入力させて処理を動的に変える方法 — ファイル選択ではなく値の入力をユーザーに求めたい場合
次にやりたくなること
- Excelファイルを自動で開いて処理して閉じる方法: ダイアログで選んだファイルを開いて処理して閉じる一連の流れをさらに詳しく知りたい場合
- ファイルやフォルダの存在を確認してから処理する方法: ダイアログで選んだパスの存在チェックやDir関数の詳細を知りたい場合
もっとカスタマイズしたい場合
「ダイアログで選んだ複数ファイルを順番に集計したい」「フォルダを選んでサブフォルダも含めて一括処理したい」「選択したファイルの内容に応じて処理を分岐させたい」など、業務に合わせたカスタマイズが必要な場合は、ココナラで相談できる。
相談時に伝えると話が早い情報:
- Excel のバージョン / OS
- 選択するファイルの種類(Excel、CSV、PDFなど)
- 選択後にやりたい処理(集計、転記、PDF変換など)
- 複数ファイルを処理するか、1ファイルずつか


コメント