このページ内の目次
どんなデータを入力データとする場合でも必要になってくるのがファイル参照とフォルダ参照の機能です。入力データの置き場所が変更される予定が無い場合であっても、マクロ内に固定で組み込んでしまうよりも汎用性のある仕組みを取り入れていくことは将来性を考えて重要であると考えます。個人でマクロを作成して実行している場合は、この限りではありません。
参照したファイルやフォルダのパスは必ず、エクセルシート側に残すことで、取り込んだファイルやフォルダが明確になります。
そして、入力データに限らず、出力結果を書き出すファイルが既存のエクセルファイルの場合、出力ファイルを指定するのにも使用できます。
ファイル選択ダイアログから、開きたいファイルを選択しよう。
①参照ボタンを押下する。
②ファイルを選択する。
③ファイルパスがエクセルのセルに格納される。
上記①~③のように動作するマクロについて考えます。
開発タブの「Visual Basic」を選択します。
ボタンを付けるシートにマクロを記入します。ここでは、「Sheet1(実行)」に記載します。「Sheet1」は、このシートのオブジェクト名であり、「実行」はエクセルの表面側から見えるシートの名前です。
' ****************************
' * 参照ボタンにマクロ登録済 *
' ****************************
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モジュールが参考になると思います。
ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行う。
マクロの有効化手順については、こちらも参考にしてください。
上記に記載したファイル参照は、ダイアログを開いたときの初期フォルダがデフォルトのため、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にオプション設定の引数を追加します。
標準モジュール側のコード(変更分)
'*********************************************************************
'
' ファイル選択ダイアログの呼び出し(初期フォルダ指定)
' 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モジュールが参考になると思います。
ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行う。
マクロの有効化手順については、こちらも参考にしてください。