ファイルの存在確認とフォルダの作成(FileSystemObject の基本)
出力先フォルダがなければ作る、同じ名前のファイルがあれば連番を付ける、といったファイル操作の基本を FileSystemObject で解説します。上書き事故を防ぐ書き方です。
どんな場面で使うか
マクロで帳票や CSV を出力するとき、出力先のフォルダがないとエラーになり、同じ名前のファイルがあると黙って上書きしてしまいます。月ごとのフォルダを自動で作り、既存のファイルを上書きしないようにしておくと、運用中の事故を防げます。
こうしたファイル操作は、Windows に標準で入っている FileSystemObject(FSO)を使うと分かりやすく書けます。
よく使う機能
FSO は CreateObject("Scripting.FileSystemObject") で作成します。よく使うのは次の機能です。
- FileExists(パス):ファイルがあるか
- FolderExists(パス):フォルダがあるか
- CreateFolder(パス):フォルダを作る(親フォルダが必要)
- GetBaseName / GetExtensionName:ファイル名と拡張子を分ける
- CopyFile / MoveFile:ファイルのコピー・移動
階層ごとにフォルダを作るコード
CreateFolder は1階層ずつしか作れないため、「出力\2026\10」のように途中のフォルダもまとめて作る関数を用意します。
Function EnsureFolder(ByVal path As String) As String
Dim fso As Object, parent As String
Set fso = CreateObject("Scripting.FileSystemObject")
If Not fso.FolderExists(path) Then
parent = fso.GetParentFolderName(path)
If parent <> "" And Not fso.FolderExists(parent) Then EnsureFolder parent
fso.CreateFolder path
End If
EnsureFolder = path
End Function同じ名前があれば連番を付けるコード
保存しようとしたファイル名がすでにあれば、「請求書(2).pdf」「請求書(3).pdf」のように番号を付けた名前を返します。
Function UniquePath(ByVal folder As String, ByVal fileName As String) As String
Dim fso As Object, base As String, ext As String, n As Long, p As String
Set fso = CreateObject("Scripting.FileSystemObject")
base = fso.GetBaseName(fileName)
ext = fso.GetExtensionName(fileName)
p = fso.BuildPath(folder, fileName)
n = 1
Do While fso.FileExists(p)
n = n + 1
p = fso.BuildPath(folder, base & "(" & n & ")." & ext)
Loop
UniquePath = p
End Function
Sub SampleSave()
Dim folder As String
folder = EnsureFolder(ThisWorkbook.Path & "\出力\" & Format(Date, "yyyy\\mm"))
MsgBox UniquePath(folder, "請求書.pdf")
End Sub注意点
ネットワーク上の共有フォルダ(\\サーバー名\共有名)でも同じように使えますが、アクセス権がないとエラーになります。また、OneDrive の同期フォルダでは、ThisWorkbook.Path が「https://」から始まる URL になる場合があり、FSO でそのまま扱えません。その場合は、出力先をローカルのフォルダに固定するか、OneDrive のローカルパスを指定してください。
- CreateFolder は1階層ずつ(関数で再帰的に作る)
- 上書きしたくない出力は連番などで回避する
- OneDrive 上のブックは Path が URL になることがある
※Format 関数で「\\」と書くと、結果に「\」が1つ入ります(年と月の間のフォルダ区切り)。
ほかの記事
基本・高速化最終行を正しく取得する方法(End(xlUp)・UsedRange・CurrentRegion の違い)データの最終行を取得する代表的な3つの方法と、空白行や書式だけ残ったセルで結果がずれる原因、実務で安全な書き方を解説します。基本・高速化マクロを速くする基本(画面更新の停止・計算の手動化・配列での一括処理)セルを1つずつ読み書きする遅いマクロを、画面更新の停止・計算方法の切り替え・配列での一括処理で速くする方法を、元に戻し忘れを防ぐ書き方とあわせて解説します。基本・高速化日付の扱い方(文字列の日付の変換・月末日・締め日の計算)CSV から取り込んだ文字列の日付を日付型に変換する方法、DateSerial を使った月末日や締め日の計算、和暦の表示など、日付で間違えやすい点をまとめます。データ集計・抽出複数シートのデータを1枚のシートに集約する支店別・月別など同じ形式の複数シートを、1枚の集計用シートにまとめるマクロです。見出しの扱い、元シート名の記録、集計シートの作り直しまで解説します。