ファビコン。井の家紋。ファイル参照-ファイル選択ダイアログ | エクセルマクロ(VBA)実践蔵(じっせんぐら)

前の項目 - マクロの初期設定と基本
次の項目 - フォルダ参照-フォルダ選択ダイアログ

ファイル参照-ファイル選択ダイアログ最終更新日:2023-10-28

このページ内の目次

はじめに - ファイル選択ダイアログを使用する重要性

どんなデータを入力データとする場合でも必要になってくるのがファイル参照とフォルダ参照の機能です。入力データの置き場所が変更される予定が無い場合であっても、マクロ内に固定で組み込んでしまうよりも汎用性のある仕組みを取り入れていくことは将来性を考えて重要であると考えます。個人でマクロを作成して実行している場合は、この限りではありません。

参照したファイルやフォルダのパスは必ず、エクセルシート側に残すことで、取り込んだファイルやフォルダが明確になります。

そして、入力データに限らず、出力結果を書き出すファイルが既存のエクセルファイルの場合、出力ファイルを指定するのにも使用できます。

ファイル選択ダイアログを表示させよう

ファイル選択ダイアログから、開きたいファイルを選択しよう。

ファイル参照(表面側の見え方)

①参照ボタンを押下する。
ファイル参照(表側の見え方)

②ファイルを選択する。
ファイル参照(ダイアログ)

③ファイルパスがエクセルのセルに格納される。
ファイル参照(ファイルパス表示)

上記①~③のように動作するマクロについて考えます。

マクロを動作させるボタンの追加方法は、こちら

ファイル参照(コード)

開発タブの「Visual Basic」を選択します。

ボタンを付けるシートにマクロを記入します。ここでは、「Sheet1(実行)」に記載します。「Sheet1」は、このシートのオブジェクト名であり、「実行」はエクセルの表面側から見えるシートの名前です。

エクセル(Excel)マクロVBA VBAProject(プロジェクト側)

 
' ****************************
' * 参照ボタンにマクロ登録済 *
' ****************************
Sub ファイル選択_Click()

Dim filename As String

'ファイル選択ダイアログの呼び出し
filename = GetFileName("全てのファイル,*.*")

If filename <> "Cancel" Then
'ファイルが選択された場合
Range("B3").Value = filename

End If

End Sub

すこし余談になりますが、VBAでは変数名や関数名(メソッド名)に日本語を使用して書くことができます。上記のように、「ファイル選択_Click()」という名前をつけることができ、エラーにはなりません。

上記のマクロをボタンが押されたときに動作するように、ボタンにマクロの登録を行います。

ボタン押下時のマクロ登録方法は、こちら

メソッド名に日本語が入っていると、マクロ登録する際に選びやすくなるため、おすすめです。

上記で呼び出しているGetFileNameという関数は、標準関数ではないため、このままでは、まだ、動作できません。このGetFileNameという関数を標準モジュールに追加します。

標準モジュールオブジェクトの追加方法は、こちら

標準モジュール側に記載するマクロ。

 
'**************************************
'
' ファイル選択ダイアログの呼び出し
'
'**************************************
Function GetFileName(filter As String) As String

Dim fname_str As String

'ファイル選択ダイアログの呼び出し
fname_str = Application.GetOpenFilename(filter)

If fname_str <> "False" Then
'選択されたとき
GetFileName = fname_str
Else
'キャンセルされたとき
GetFileName = "Cancel"
End If

End Function

シート側にすべてのマクロを記載することも、標準モジュール側にマクロを記載することも可能ですが、それぞれに役割があります。

役割については、マクロを記述できる場所のそれぞれの特長についてのマクロを書く場所によるコードの違いで触れているため、気になる方はそちらも参照してみてください。

それに倣って、シート側には、主にフォームコントロールにマクロ登録されている関数を記述するようにしています。

別のマクロでも再利用できる可能性のある処理は、関数として、標準モジュールに切り出しておくと、インポート/エクスポート機能がついているため、使いまわすのに便利です。

汎用性のないコードに関しては、再利用できる関数群と明確に切り分けられていれば、どちらに書いても良いかなと思います。

この後、エクセルファイルを開く場合は、OpenBookモジュールが参考になると思います。

エクセルマクロ有効ブックのダウンロード

ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行う。

マクロの有効化手順については、こちらも参考にしてください。

ファイル参照 エクセルファイル(xlsm)のダウンロード

ファイル選択ダイアログ 初期フォルダ指定 ネットワークドライブでも大丈夫

上記に記載したファイル参照は、ダイアログを開いたときの初期フォルダがデフォルトのため、PCに依存します。そのため、Cドライブの先頭(C:\)や、ユーザのドキュメントフォルダが始めに開きます。但し、エクセルを開いてから最初にファイル選択ダイアログを呼んだ場合に限ります。

前回のままでも、エクセルを開いてから一度ファイル選択ダイアログからファイルを選択後に、再度、ファイル選択ダイアログを呼び出す場合は、前回選択したファイルが置いてあるフォルダが始めに開きます。(エクセル表側は変更なし。)

そのため、エクセルを開いた直後のファイル選択ダイアログに対して、初期フォルダを指定したい場合についての対処方法を記載していきます。前回マクロを実行したときのファイルパスがセルに残されていた場合(エクセル表側 B3セル)に、そのパスを使用し、ファイル選択ダイアログを開くときの初期フォルダに設定したいと思います。このとき、ネットワーク上のドライブや外付けドライブであっても、初回フォルダに設定できるように考慮しています。

(例)「C:\」ドライブ ←→「L:\」ドライブ

シート側のコードを変更します。FileSystemObjectを呼び出しているため、参照設定ダイアログにてMicrosoft Scripting Runtimeの事前追加が必要です。FileSystemObject使用時の設定を参照してください。今回は、ファイルパスからディレクトリパスを抽出しているだけのため、文字列操作に変更しても構いません。

シートオブジェクトに記載するコード

 
' ****************************
' * 参照ボタンにマクロ登録済 *
' ****************************
Sub ファイル選択_Click()

Dim filename As String

'ファイル選択ダイアログの呼び出し
filename = GetFileName("全てのファイル,*.*", Range("B3").Value)

If filename <> "Cancel" Then
'ファイルが選択された場合
Range("B3").Value = filename

End If

End Sub

標準モジュールのGetFileNameにオプション設定の引数を追加します。

標準モジュール側のコード(変更分)

GetFileName関数(初期フォルダ指定)

 
'*********************************************************************
'
' ファイル選択ダイアログの呼び出し(初期フォルダ指定)
' 2023/08/20 Update 初期フォルダにファイルパスを使用できるように対応
' 第2引数 OpenDirは フォルダパス又はファイルパス
'
'*********************************************************************
Function GetFileName(filter As String, Optional ByVal OpenDir As String = "") As String

Dim fname_str As String
Dim strCurFolder, strCurDrive As String
Dim strMoveDrive As String
Dim FileSysObj As New FileSystemObject
Dim ShellScrpt As Object

If OpenDir = "" Then
'初期ディレクトリ指定なしの場合

'ファイル選択ダイアログの呼び出し
fname_str = Application.GetOpenFilename(filter)

Else
'初期ディレクトリ指定ありの場合

'ファイルパスの場合、フォルダパスに変換
If FileSysObj.FileExists(OpenDir) = True Then
OpenDir = FileSysObj.GetParentFolderName(OpenDir)
ElseIf InStr(1, OpenDir, ".", vbTextCompare) > 0 Then
OpenDir = FileSysObj.GetParentFolderName(OpenDir)
End If

'現在のドライブを取得
strCurFolder = CurDir
strCurDrive = Strings.Left(strCurFolder, 3)

'移行先のドライブを取得
strMoveDrive = Strings.Left(OpenDir, 3)

Set ShellScrpt = CreateObject("WScript.Shell")
'別ドライブへ移動する場合
If Not StrComp(strMoveDrive, strCurDrive, vbTextCompare) = 0 And _
FileSysObj.DriveExists(strMoveDrive) = True Then

ShellScrpt.CurrentDirectory = strMoveDrive

'ファイル選択ダイアログを開く時の先頭ディレクトリを設定
'(カレントディレクトリ変更)
'ChDir OpenDir

End If

'エラー系対処の追加 2023/10/28
'ドライブが存在するなら、初期ディレクトリ変更
If Not Dir(OpenDir, vbDirectory) = "" Then
ChDir OpenDir
End If

'ファイル選択ダイアログの呼び出し
fname_str = Application.GetOpenFilename(filter)

'カレントフォルダを元に戻す
'別ドライブへ移動していた場合
If Not StrComp(strMoveDrive, strCurDrive, vbTextCompare) = 0 And _
FileSysObj.DriveExists(strMoveDrive) = True Then

ShellScrpt.CurrentDirectory = strCurDrive

'カレントフォルダを元に戻す
ChDir strCurFolder
End If
End If

If fname_str <> "False" Then
'選択されたとき
GetFileName = fname_str
Else
'キャンセルされたとき
GetFileName = "Cancel"
End If

End Function

これで、前回参照したファイルのそばに新しく指定したいファイルが存在する場合は、操作が楽になります。

この後、エクセルファイルを開く場合は、OpenBookモジュールが参考になると思います。


フォルダ参照(初回に開く初期フォルダ指定版)のエクセルマクロ有効ブックのダウンロード

ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行う。

マクロの有効化手順については、こちらも参考にしてください。

ファイル参照(初回フォルダ指定) エクセルファイル(xlsm)のダウンロード

前の項目 - マクロの初期設定と基本
次の項目 - フォルダ参照-フォルダ選択ダイアログ