複数のExcelファイルやCSVファイルをまとめて取り込みたいとき、ファイルを1つずつ選んで実行するのは面倒です。Application.GetOpenFilename に MultiSelect:=True を指定すると、ダイアログ上で複数ファイルを一度に選択させることができます。
この記事では、GetOpenFilename の基本的な使い方から、複数選択時の戻り値の扱い方、キャンセル時のエラー対策、選択したファイルを順番に処理する実践コードまで解説します。
GetOpenFilenameの基本
Application.GetOpenFilename は、ファイルを開くダイアログを表示し、ユーザーが選択したファイルパスを文字列で返すメソッドです。実際にファイルを開くわけではなく、パスを取得するだけという点がポイントです。
Sub GetSingleFile()
Dim filePath As Variant
filePath = Application.GetOpenFilename("Excelブック,*.xlsx;*.xls", , "ファイルを選択してください")
If filePath = False Then
MsgBox "ファイルが選択されませんでした"
Exit Sub
End If
MsgBox "選択されたファイル:" & filePath
End Sub
第1引数はファイルフィルタで、「表示名,フィルタパターン」の形式で指定します。ユーザーがキャンセルした場合、戻り値は文字列ではなく False(Boolean)になるため、戻り値の型は Variant で受け取る必要があります。
複数ファイルを選択する:MultiSelect:=True
複数ファイルを選択させたい場合は、第4引数に MultiSelect:=True を指定します。すると戻り値は単一の文字列ではなく、選択したファイルパスの配列(Variant型の1次元配列)になります。
Sub GetMultipleFiles()
Dim filePaths As Variant
filePaths = Application.GetOpenFilename( _
FileFilter:="Excelブック,*.xlsx;*.xls", _
Title:="複数のファイルを選択してください", _
MultiSelect:=True)
If Not IsArray(filePaths) Then
MsgBox "ファイルが選択されませんでした"
Exit Sub
End If
Dim i As Long
For i = LBound(filePaths) To UBound(filePaths)
Debug.Print filePaths(i)
Next i
End Sub
キャンセル時は False(配列ではない)が返るため、IsArray(filePaths) で判定するのが確実です。filePaths = False のような比較でチェックすると、配列同士の比較でエラーになることがあるため注意してください。
選択したファイルを順番に開いて処理する
複数ファイルを選択させたあと、それぞれのブックを開いてデータを転記するような処理を組んでみます。
Sub ImportMultipleFiles()
Dim filePaths As Variant
filePaths = Application.GetOpenFilename( _
FileFilter:="Excelブック,*.xlsx;*.xls", _
Title:="取り込むファイルを選択してください", _
MultiSelect:=True)
If Not IsArray(filePaths) Then
MsgBox "ファイルが選択されませんでした"
Exit Sub
End If
Dim destWs As Worksheet
Set destWs = ThisWorkbook.Worksheets("集計")
Dim destRow As Long
destRow = destWs.Cells(destWs.Rows.Count, "A").End(xlUp).Row + 1
Application.ScreenUpdating = False
Dim i As Long
For i = LBound(filePaths) To UBound(filePaths)
Dim srcWb As Workbook
Set srcWb = Workbooks.Open(filePaths(i), ReadOnly:=True)
Dim srcWs As Worksheet
Set srcWs = srcWb.Worksheets(1)
Dim lastRow As Long
lastRow = srcWs.Cells(srcWs.Rows.Count, "A").End(xlUp).Row
If lastRow >= 2 Then
srcWs.Range("A2:C" & lastRow).Copy destWs.Cells(destRow, "A")
destRow = destRow + (lastRow - 1)
End If
srcWb.Close SaveChanges:=False
Next i
Application.ScreenUpdating = True
MsgBox "取り込みが完了しました"
End Sub
各ブックは ReadOnly:=True で開き、コピー後は SaveChanges:=False で必ず閉じています。開いたブックを閉じ忘れると、Excelが裏で大量に起動したままになるため、Workbooks.Open と Close は必ずセットで書くことを意識してください。
ファイル名だけを取り出す
filePaths(i) にはフルパスが入っているため、ファイル名だけを表示したい場合は InStrRev と Mid を組み合わせて取り出します。
Sub ShowFileNameOnly()
Dim fullPath As String
fullPath = "C:\Users\sample\Documents\売上データ.xlsx"
Dim fileName As String
fileName = Mid(fullPath, InStrRev(fullPath, "\") + 1)
MsgBox fileName ' 売上データ.xlsx
End Sub
InStrRev で最後の「\」の位置を後ろから検索し、その次の文字から Mid で取り出すことで、パスの区切り文字の数に関わらずファイル名だけを抽出できます。
フィルタで複数の拡張子を指定する
CSVとExcelファイルの両方を選択対象にしたい場合は、フィルタ文字列を「;」区切りで複数指定します。
Sub GetOpenFilenameMultiFilter()
Dim filePaths As Variant
filePaths = Application.GetOpenFilename( _
FileFilter:="対応ファイル,*.xlsx;*.xls;*.csv,Excelブック,*.xlsx;*.xls,CSVファイル,*.csv", _
Title:="ファイルを選択してください", _
MultiSelect:=True)
If Not IsArray(filePaths) Then Exit Sub
Dim i As Long
For i = LBound(filePaths) To UBound(filePaths)
Debug.Print filePaths(i)
Next i
End Sub
「表示名,パターン」の組を複数並べることで、ダイアログの「ファイルの種類」ドロップダウンに複数の選択肢を表示できます。
まとめ
Application.GetOpenFilename に MultiSelect:=True を指定するだけで、複数ファイルの一括選択をユーザーに委ねる処理が簡単に作れます。
- 戻り値は選択キャンセル時に
False、選択時は配列になるためIsArrayで判定する - 選択後は
Workbooks.Open→ 処理 →Workbooks.Closeを必ずセットで書く - ファイル名だけが欲しい場合は
InStrRevとMidを組み合わせる - フィルタは「表示名,パターン」の組を「,」区切りで複数指定できる
複数ファイルの取り込み作業を自動化する第一歩として、ぜひ実務のマクロに取り入れてみてください。

コメント