【VBA】フォルダ選択ダイアログでユーザーに処理先を選ばせる方法(コピペOK)

VBA
スポンサーリンク

スポンサーリンク

この記事でできること

VBAでフォルダ選択ダイアログを表示して、ユーザーに処理先フォルダを選ばせる方法が分かる。

  • 対象:マクロの処理先フォルダをコードに直書きしたくない人
  • 所要時間:コピペ → 実行まで5分

どんな場面で使う?

  • マクロの処理先フォルダをコードに直書きせず、実行時にユーザーに選ばせたいとき
  • 同僚にマクロを渡したとき「パスが見つかりません」エラーを防ぎたいとき
  • 出力先フォルダを毎回変えるマクロで柔軟な運用をしたいとき
  • バックアップ先やエクスポート先をユーザーに選択させたいとき

導入

以前、月次データを特定フォルダに出力するマクロを作ったとき、フォルダパスをコードに直書きしていた。自分のPCでは動くけど、同僚に渡したら「パスが見つかりません」とエラーが出て、そのたびにパスを書き換えてもらう羽目になった。正直めんどくさかった(①共感)。

フォルダ選択ダイアログを使うようにしてからは、誰のPCでもそのまま動くマクロになった。「どこに保存しますか?」とダイアログが出るので、使う人が迷わない(②実感)。

この記事で、同じように「パスの直書きをやめたい」「マクロを他の人にも使ってもらいたい」という人がサクッと対応できるようになればうれしい(③動機)。

ファイル(フォルダではなく個別ファイル)を選ばせたい場合は ファイル選択ダイアログでユーザーにファイルを選ばせる方法 を参照。

Before / After

Before:フォルダパスをコードに直書き


Dim folderPath As String
folderPath = "C:\Users\tanaka\Desktop\月次レポート"
' → 別のPCではエラーになる

After:ダイアログでユーザーが選択


Dim folderPath As String
With Application.FileDialog(msoFileDialogFolderPicker)
    If .Show = -1 Then folderPath = .SelectedItems(1)
End With
' → どのPCでも動く

手順

  1. Excelファイルを.xlsmで保存する

マクロ有効ブック(.xlsm)でないとVBAは保存できない。

  1. VBEを開く

Alt + F11 でVBE(コードを書く画面)を開く。

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

VBEのメニュー →「挿入」→「標準モジュール」。

  1. コードを貼り付ける

下のコードをそのままコピーして貼り付ける。

  1. 実行する

F5 キー、またはVBEのメニュー →「実行」→「Sub/ユーザーフォームの実行」。

基本コード(フォルダパス取得)


Sub SelectFolder()
    '============================================
    ' フォルダ選択ダイアログでパスを取得する
    ' キャンセル時は処理を中断
    '============================================

    Dim folderPath As String

    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "処理するフォルダを選択してください"

        If .Show = -1 Then
            ' --- ユーザーがフォルダを選択した場合 ---
            folderPath = .SelectedItems(1)
            MsgBox "選択されたフォルダ:" & vbCrLf & folderPath, vbInformation
        Else
            ' --- キャンセルされた場合 ---
            MsgBox "キャンセルされました。処理を中断します。", vbExclamation
            Exit Sub
        End If
    End With

    ' ここから folderPath を使った処理を書く
    ' 例: Dir(folderPath & "\*.xlsx") でファイル一覧を取得
End Sub

ポイント

  • Application.FileDialog(msoFileDialogFolderPicker) でフォルダ選択ダイアログを取得
  • .Show メソッドでダイアログを表示。戻り値は -1(選択) または 0(キャンセル)
  • .SelectedItems(1) で選択されたフォルダのパスを取得(末尾に \ は付かない)

実務版コード(初期フォルダ指定+キャンセル処理+存在確認付き)

実務では、初期フォルダの指定やパスの存在確認まで入れておくと、ユーザーの操作ミスを防げる。自分はこの形をテンプレートにしていて、フォルダ操作系のマクロは全部これをベースに書いている。


Sub SelectFolderAdvanced()
    '============================================
    ' 実務版:フォルダ選択ダイアログ
    ' - 初期フォルダ指定
    ' - キャンセル処理
    ' - 選択パスの存在確認
    ' - 末尾の\を統一
    '============================================

    Dim folderPath As String
    Dim initialPath As String

    ' --- 初期フォルダを設定(ここを変更すると開く場所が変わる) ---
    initialPath = ThisWorkbook.Path    ' ←このブックと同じフォルダ
    ' initialPath = "C:\Users\" & Environ("USERNAME") & "\Desktop"  ' ←デスクトップ

    ' --- 初期フォルダが存在しない場合のフォールバック ---
    If Dir(initialPath, vbDirectory) = "" Then
        initialPath = Environ("USERPROFILE") & "\Desktop"
    End If

    With Application.FileDialog(msoFileDialogFolderPicker)
        .Title = "処理するフォルダを選択してください"
        .InitialFileName = initialPath & "\"    ' ←末尾に\を付けることで初期フォルダとして認識される

        ' --- ダイアログ表示 ---
        If .Show = 0 Then
            MsgBox "キャンセルされました。処理を中断します。", vbExclamation
            Exit Sub
        End If

        folderPath = .SelectedItems(1)
    End With

    ' --- 選択パスの存在確認(念のため) ---
    If Dir(folderPath, vbDirectory) = "" Then
        MsgBox "選択されたフォルダが見つかりません:" & vbCrLf & _
               folderPath, vbCritical
        Exit Sub
    End If

    ' --- 末尾の\を統一(パス結合時のミス防止) ---
    If Right(folderPath, 1) <> "\" Then
        folderPath = folderPath & "\"
    End If

    ' ===== ここから実際の処理 =====
    ' 例:選択フォルダ内のExcelファイル一覧を取得
    Dim fileName As String
    Dim fileCount As Long

    fileName = Dir(folderPath & "*.xlsx")
    Do While fileName <> ""
        fileCount = fileCount + 1
        Debug.Print fileCount & ": " & fileName
        fileName = Dir()
    Loop

    MsgBox "フォルダ: " & folderPath & vbCrLf & _
           "Excelファイル数: " & fileCount, vbInformation
End Sub

実務版の追加ポイント

  • InitialFileName で初期フォルダを指定(末尾に \ を付ける)
  • ThisWorkbook.Path を使えばブックと同じフォルダが初期表示される
  • 選択後も Dir(folderPath, vbDirectory) で存在確認を入れておくと安全
  • パスの末尾に \ を統一しておくと、後続のファイル操作でパス結合ミスが起きない

フォルダの自動作成については フォルダを自動作成して振り分ける方法 を参照。フォルダやファイルの存在確認をもっと詳しく知りたい場合は ファイルやフォルダの存在を確認してから処理する方法 にまとめてある。

Shell.Application.BrowseForFolder との比較

フォルダ選択にはもう1つ、Shell.ApplicationBrowseForFolder メソッドを使う方法がある。

BrowseForFolder の基本コード


Sub SelectFolderShell()
    '============================================
    ' Shell.Application.BrowseForFolder でフォルダ選択
    ' 古い方法だが、特殊フォルダの指定が可能
    '============================================

    Dim shell As Object
    Dim folder As Object
    Dim folderPath As String

    Set shell = CreateObject("Shell.Application")
    Set folder = shell.BrowseForFolder(0, "フォルダを選択してください", &H1, "C:\")

    If folder Is Nothing Then
        MsgBox "キャンセルされました。", vbExclamation
        Exit Sub
    End If

    folderPath = folder.Self.Path

    MsgBox "選択されたフォルダ:" & vbCrLf & folderPath, vbInformation
End Sub

比較表

項目 Application.FileDialog Shell.BrowseForFolder
ダイアログの見た目 Windows標準の最新UI やや古いUI
初期フォルダ指定 .InitialFileName で簡単 第4引数でルート指定(やや面倒)
新しいフォルダ作成 ダイアログ内で可能 フラグ指定で可能
パスの取得 .SelectedItems(1) folder.Self.Path
参照設定 不要(VBA標準) 不要(CreateObject)
ネットワークパス対応 対応 一部制限あり
おすすめ度 ★★★(推奨) ★★(特殊用途向け)

結論:通常は Application.FileDialog を使えばよい。 UIが新しく、操作も直感的で、初期フォルダの指定も簡単。Shell.BrowseForFolder は、デスクトップやマイコンピュータなどの特殊フォルダをルートに指定したい場合に限り使う。

落とし穴

# 症状 原因 対策
1 .InitialFileName を指定しても初期フォルダが反映されない 末尾に \ を付けていない。\ がないとファイル名として解釈される initialPath & "\" のように 末尾に\を付ける
2 .SelectedItems(1) でエラーが出る キャンセル時にSelectedItemsにアクセスしている 必ず .Show の戻り値を先にチェック してからSelectedItemsにアクセスする
3 パス結合で \\ が入ってしまう 選択パスの末尾に \ があるかないかが環境によって異なる 取得後に Right(folderPath, 1) <> "\" で末尾を統一する
4 ネットワークドライブのフォルダが選べない ネットワーク接続が切れている、またはアクセス権限がない ダイアログ表示前にネットワーク接続を確認する。Dir でアクセスチェックを入れる
5 自分のPCでは動くが他のPCでは初期フォルダがエラーになる InitialFileName に自分のPC固有のパスをハードコードしている。自分もこれで同僚から「動かない」と言われて30分原因を探した ThisWorkbook.PathEnviron("USERPROFILE") など、環境に依存しないパスを使う
6 msoFileDialogFolderPicker で定数エラーが出る VBEの参照設定で「Microsoft Office XX.X Object Library」が外れている(通常は自動で入っている) 定数の代わりに直接数値 4 を指定する。Application.FileDialog(4) でも同じ動作

VBAのフォルダ選択ダイアログが開かないときの対処法

「FileDialogを実行してもダイアログが表示されない」という場合、原因はmsoFileDialogFolderPickerの定数が認識されていないことだ。参照設定で「Microsoft Office XX.0 Object Library」が外れている場合、定数値 4 を直接指定する。Application.FileDialog(4) で動作する。

VBAでフォルダ選択のキャンセル時にエラーになるときの対処法

「ダイアログでキャンセルを押すとエラーが出る」という場合、原因はShowメソッドの戻り値チェック漏れだ。Showは選択時に-1、キャンセル時に0を返す。If .Show = 0 Then Exit Sub のようにキャンセル判定を入れれば安全に処理を中断できる。

FAQ

Q1. フォルダ選択ではなくファイル選択ダイアログを出したい場合は?

A. msoFileDialogFolderPicker の代わりに msoFileDialogFilePicker を使う。詳しくは ファイル選択ダイアログでユーザーにファイルを選ばせる方法 を参照。

Q2. 複数のフォルダを一度に選択できますか?

A. Application.FileDialog(msoFileDialogFolderPicker) では1つのフォルダしか選択できない。複数フォルダを処理したい場合は、ループで複数回ダイアログを表示するか、親フォルダを選ばせてサブフォルダを自動取得する方法がある。フォルダ一覧の取得は フォルダ内ファイル一覧を自動取得 を参照。

Q3. ダイアログのタイトルバーの文字を変えられますか?

A. .Title プロパティで変更できる。


With Application.FileDialog(msoFileDialogFolderPicker)
    .Title = "出力先フォルダを選んでください"
    .Show
End With

Q4. デスクトップを初期フォルダにしたい場合は?

A. Environ 関数でデスクトップのパスを取得できる。


.InitialFileName = Environ("USERPROFILE") & "\Desktop\"

自分はこの方法で落ち着いている。CreateObject("WScript.Shell").SpecialFolders("Desktop") でも取得できるが、Environ のほうがシンプル。

Q5. 選択されたフォルダが空かどうかチェックしたい場合は?

A. Dir 関数でファイルの有無を確認できる。


If Dir(folderPath & "\*.*") = "" Then
    MsgBox "フォルダが空です。処理を中断します。", vbExclamation
    Exit Sub
End If

まとめ

この記事では、フォルダ選択ダイアログでユーザーに処理先を選ばせる方法 を解説した。

  • 基本:Application.FileDialog(msoFileDialogFolderPicker) でダイアログ表示、.SelectedItems(1) でパス取得
  • 実務:初期フォルダ指定(InitialFileName)+キャンセル処理+存在確認+末尾\統一
  • Shell.BrowseForFolder は古いUIだが特殊フォルダ指定に使える。通常は FileDialog で十分

バックアップの推奨: フォルダ内のファイルを操作するマクロと組み合わせる場合、処理前にフォルダごとバックアップを取っておくことを推奨する。

前提条件

項目 内容
Excel版 Excel 2016以降 / Microsoft 365
OS Windows 10 / 11
保存形式 .xlsm(マクロ有効ブック)
貼り付け場所 標準モジュール
実行方法 F5 キー、またはマクロ実行

次にやりたくなること

コメント

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