【PR】を含みます。

プログラミング

【VBA】ファイル選択ダイアログを実装する方法2選(GetOpenFilename / FileDialog)

VBA ファイル選択ダイアログを実装する方法2選(GetOpenFilename / FileDialog)

Excel VBAでは「ユーザーにファイルを選ばせたい」という場面がよくあります。

たとえば、取り込み対象のCSVや別ブックを選択してもらったり、任意のファイルパスを取得して処理に渡したりと、実務でもよく使います。

この記事では、Windows APIを使わずに、Excelの標準機能だけで実装できる「ファイル選択ダイアログ」の代表的な方法を2つ紹介します。

さらに番外編として、フォルダ選択(FolderPicker)もあわせて解説します。

どれもコピペで動くサンプル付きです。

※Windows API(GetOpenFileName など)を使う方法もありますが、32/64bit対応や宣言の違いなどで難易度が上がるため、本記事では扱いません。

迷ったらこれ(使い分け早見)

用途別に「どれを使うべきか」を先にまとめます。

迷ったらこの判断でOKです。

  • とにかく最短で実装したいGetOpenFilename(最小コードでパス取得)
  • 初期表示位置(フォルダ)/拡張子フィルタ/複数選択を細かく制御したいFileDialog(FilePicker)
  • フォルダを選ばせたいFileDialog(FolderPicker)

補足:業務では「初期表示位置(フォルダ)固定」や「拡張子フィルタ」が必要になることが多いため、迷うならFileDialogを選ぶのが無難です。

方法1:GetOpenFilename(最短で実装できる定番)

Application.GetOpenFilenameは、最小コードでファイル選択を実装できます。

選択結果は「ファイルパス(文字列)」として返ってくるため扱いやすく、まずはこれを覚えるのがおすすめです。

特徴

  • 実装がとにかく簡単
  • 参照設定など不要
  • キャンセル時はFalseが返るため判定が必要
  • 初期表示位置(フォルダ)をプロパティで指定することはできません。表示位置は、直前の操作状況やカレントフォルダなどに影響されます
    ※厳密には ChDir でカレントフォルダを変えてから表示する方法もありますが、挙動が環境や操作履歴の影響を受けやすいため、確実に固定したい場合はFileDialogを推奨します。
  • フィルタや複数選択など、UIの細かい制御はFileDialogの方が得意

【サンプルコード】GetOpenFilename

Copyをクリックするとコピーできます。

VBA
Copy
Sub PickFile_GetOpenFilename()
    Dim filePath As Variant '選択結果(パス文字列 or False)
    'ファイル選択ダイアログを表示
    '表示する拡張子を指定
    'ダイアログのタイトル
    '複数選択しない
    filePath = Application.GetOpenFilename( _
        FileFilter:="Excelファイル (*.xlsx;*.xlsm;*.xls),*.xlsx;*.xlsm;*.xls,すべてのファイル (*.*),*.*", _
        Title:="ファイルを選択してください", _
        MultiSelect:=False _
    )
    If VarType(filePath) = vbBoolean Then Exit Sub 'キャンセル時はFalseになるため終了
    MsgBox "選択されたファイル:" & vbCrLf & CStr(filePath), vbInformation '選択されたパスを表示
End Sub

方法2:FileDialog(標準機能で一番実務向き)

Application.FileDialog(msoFileDialogFilePicker)は、実務で一番使われやすい方法です。

フィルタ、タイトル、初期表示位置(フォルダ)などを柔軟に設定できます。

特徴

  • フィルタの追加・削除が簡単
  • タイトル、初期表示位置(フォルダ)など調整しやすい
  • 後述の応用(複数選択など)にもつながる
  • SelectedItemsから取得する必要がある

【サンプルコード】FileDialog

Copyをクリックするとコピーできます。

VBA
Copy
Sub PickFile_FileDialogBasic()
    Dim fd As FileDialog 'ファイル選択ダイアログ用オブジェクト
    Dim filePath As String '選択されたファイルパス
    Set fd = Application.FileDialog(msoFileDialogFilePicker) 'ファイル選択ダイアログを作成
    With fd
        .Title = "ファイルを選択してください" 'タイトル
        .AllowMultiSelect = False '複数選択しない
        .Filters.Clear '既存のフィルタをクリア
        .Filters.Add "Excelファイル", "*.xlsx;*.xlsm;*.xls" 'Excelのみ表示
        .Filters.Add "すべてのファイル", "*.*" '全ファイル表示
        If .Show <> -1 Then Exit Sub 'OK以外(キャンセルなど)なら終了
        filePath = .SelectedItems(1) '選択された1件目のパスを取得
    End With
    MsgBox "選択されたファイル:" & vbCrLf & filePath, vbInformation '選択されたパスを表示
End Sub

応用:FileDialogの実用設定(初期表示位置/拡張子フィルタ/複数選択)

方法2のFileDialogは、設定を少し変えるだけで使い勝手が大きく向上します。

ここでは実務でよく使う設定パターンとして、「初期表示位置(フォルダ)」「拡張子の絞り込み」「複数選択」をまとめて紹介します。

【サンプルコード】初期表示位置(フォルダ)を指定する

毎回「同じフォルダから選ばせたい」場合に便利です。

InitialFileNameには「フォルダパス(末尾に\付き)」を指定します。
例:ThisWorkbook.Path & "\"のようにすると、そのフォルダを初期表示位置として開けます。

Copyをクリックするとコピーできます。

VBA
Copy
Sub PickFile_InitialFolder()
    Dim fd As FileDialog 'ファイル選択ダイアログ
    Dim filePath As String '選択されたパス
    Set fd = Application.FileDialog(msoFileDialogFilePicker) 'FilePickerを作成
    With fd
        .Title = "ファイルを選択してください" 'タイトル
        .AllowMultiSelect = False '単一選択
        .Filters.Clear 'フィルタ初期化
        .Filters.Add "Excelファイル", "*.xlsx;*.xlsm;*.xls" 'Excelのみ
        .InitialFileName = ThisWorkbook.Path & "\" '初期表示位置(フォルダ)をこのブックの場所にする
        If .Show <> -1 Then Exit Sub 'キャンセルなら終了
        filePath = .SelectedItems(1) '選択されたパス
    End With
    MsgBox filePath, vbInformation '確認用に表示
End Sub

補足:ThisWorkbook.Pathは「このマクロが入っているブックのフォルダ」です
「毎回このブックと同じ場所から選ばせたい」なら鉄板です。

【サンプルコード】特定の拡張子だけに絞る

対象がExcel以外のときも同じ考え方で絞り込めます。

たとえばCSVだけを選ばせたい場合は以下のように実装します。

Copyをクリックするとコピーできます。

VBA
Copy
Sub PickFile_CsvOnly()
    Dim fd As FileDialog 'ファイル選択ダイアログ
    Dim filePath As String '選択されたパス
    Set fd = Application.FileDialog(msoFileDialogFilePicker) 'FilePickerを作成
    With fd
        .Title = "CSVファイルを選択してください" 'タイトル
        .AllowMultiSelect = False '単一選択
        .Filters.Clear 'フィルタ初期化
        .Filters.Add "CSVファイル", "*.csv" 'CSVのみ表示
        If .Show <> -1 Then Exit Sub 'キャンセルなら終了
        filePath = .SelectedItems(1) '選択されたパス
    End With
    MsgBox filePath, vbInformation '確認用に表示
End Sub

複数選択に切り替える

「単一選択」だけでなく「複数ファイル選択」も同じダイアログで実現できます。

ポイントは.AllowMultiSelect = Trueにして、SelectedItemsをループさせる点です。

Copyをクリックするとコピーできます。

VBA
Copy
Sub PickFiles_MultiSelect()
    Dim fd As FileDialog 'ファイル選択ダイアログ
    Dim item As Variant 'SelectedItemsを受け取る変数
    Set fd = Application.FileDialog(msoFileDialogFilePicker) 'FilePickerを作成
    With fd
        .Title = "ファイルを選択してください(複数可)" 'タイトル
        .AllowMultiSelect = True '複数選択を許可
        .Filters.Clear 'フィルタ初期化
        .Filters.Add "Excelファイル", "*.xlsx;*.xlsm;*.xls" 'Excelのみ
        .Filters.Add "すべてのファイル", "*.*" '全ファイル
        If .Show <> -1 Then Exit Sub 'キャンセルなら終了
    End With
    For Each item In fd.SelectedItems '選択された全ファイルをループ
        Debug.Print CStr(item) 'イミディエイトに出力
    Next item
    MsgBox "選択されたファイルはイミディエイトウィンドウに出力しました。", vbInformation '完了メッセージ
End Sub

補足:複数選択は便利ですが、処理時間が増える可能性があるため大量ファイルを扱う場合は「読み取り専用で開く」「画面更新を切る」などもセットで検討すると安心です。

番外編:フォルダ選択ダイアログ(FolderPicker)もよく使う

「ファイルではなくフォルダを選ばせたい」場合は、msoFileDialogFolderPickerを使います。

たとえば「選んだフォルダ配下のCSVをまとめて処理したい」などの実務でよく登場します。

【サンプルコード】FolderPicker(フォルダパスを取得)

Copyをクリックするとコピーできます。

VBA
Copy
Sub PickFolder_FolderPicker()
    Dim fd As FileDialog 'フォルダ選択ダイアログ
    Dim folderPath As String '選択されたフォルダパス
    Set fd = Application.FileDialog(msoFileDialogFolderPicker) 'フォルダ選択用ダイアログを作成
    With fd
        .Title = "フォルダを選択してください" 'タイトル
        .InitialFileName = ThisWorkbook.Path & "\" '初期表示位置(フォルダ)(末尾\があると安定)
        If .Show <> -1 Then Exit Sub 'キャンセルなら終了
        folderPath = .SelectedItems(1) '選択されたフォルダパス
    End With
    MsgBox "選択されたフォルダ:" & vbCrLf & folderPath, vbInformation '確認用
End Sub

補足:FolderPickerでもキャンセルは普通に発生します。If .Show <> -1 Then Exit Subは必ず入れてください。

キャンセル時の処理は必須

ファイル選択ダイアログは、ユーザーがキャンセルするのが普通に起こります。

そのため、必ず以下のように「キャンセルなら終了」を入れておくのが定石です。

  • GetOpenFilenameIf VarType(filePath) = vbBoolean Then Exit Sub
  • FileDialogIf .Show <> -1 Then Exit Sub

この1行があるだけで、エラーや想定外の動作を防げます。

よくある質問(FAQ)

GetOpenFilenameで初期表示位置(フォルダ)を固定できますか?

基本的にGetOpenFilename単体では「初期表示位置(フォルダ)をプロパティで指定」できません。

表示位置は、直前の操作状況やカレントフォルダなどの影響を受けます。

初期表示位置(フォルダ)を確実に制御したい場合は、FileDialogを使うのが定石です。

FileDialogのInitialFileNameはファイルでもフォルダでも指定できますか?

用途によりますが、ファイル選択(FilePicker)の場合は「フォルダパス」を指定する使い方が一般的です。

ポイント:フォルダパスを指定する場合は末尾に\を付けると安定します。(例:ThisWorkbook.Path & "\"

FileDialogのShowの戻り値は何ですか?

.Showは、ユーザーがOKした場合に-1を返します。

キャンセルされた場合は0が返るため、If .Show <> -1 Then Exit Subで安全に終了できます。

複数選択の結果は配列ではないのですか?

AllowMultiSelect = Trueにすると、選択結果はSelectedItems(コレクション)に入ります。

配列ではないため、For Eachで回すのが基本です。

まとめ

VBAでファイル選択ダイアログを実装する方法は、Windows APIを使わなくても十分に実用的です。

  • 最短で実装したいGetOpenFilename
  • 実務で使いやすく作りたいFileDialog(FilePicker)
  • さらに便利にしたいFileDialogのカスタマイズ(初期表示位置(フォルダ)/拡張子フィルタ/複数選択)

まずはGetOpenFilenameFileDialogで動かして、必要に応じて初期表示位置(フォルダ)/拡張子フィルタ/複数選択などの設定を足していくのがおすすめです。

-プログラミング
-,