概要
Excel VBAを用いた業務自動化において、最も頻繁に直面する課題の一つが「動的なフォルダ作成とファイル保存」です。特に、月次や案件ごとにフォルダを階層構造で管理している場合、保存先が存在しないことでエラーが発生し、処理が中断してしまう経験は多くのエンジニアが通る道でしょう。
本記事では、単なる「フォルダ作成」にとどまらず、存在しない複数階層のフォルダを再帰的、あるいは逐次的にチェックして生成し、その直下にブックを保存するプロフェッショナルな手法を解説します。エラーハンドリングを完璧にこなし、堅牢で再利用性の高いコードを実装する技術を習得しましょう。
詳細解説:なぜ複数階層の作成が難しいのか
VBA標準の「MkDir」関数は、単一のフォルダを作成するには適していますが、親フォルダが存在しない状態でサブフォルダを作成しようとすると「パスが見つかりません」というエラーを返します。例えば、「C:\Reports\2023\October」という階層を作成したい場合、「Reports」フォルダがない状態でいきなり「October」を作ろうとすれば失敗します。
この課題を解決するためのアプローチは主に2つあります。
1.FileSystemObject(FSO)を使用する方法(推奨)
2.シェルコマンド(MkDir)を再帰的に呼び出す方法
実務においては、Windows環境との親和性が高く、ファイル操作系メソッドが豊富に揃っている「FileSystemObject」を利用するのがベストプラクティスです。FSOの「FolderExists」メソッドで存在を確認し、なければ「CreateFolder」を実行するロジックを組むことで、階層がいくつあっても確実に目的のフォルダを作成できます。
サンプルコード:FSOを用いた堅牢なフォルダ生成と保存
以下のコードは、指定されたパスを解析し、欠損している階層を自動生成した上でブックを保存する汎用プロシージャです。
Option Explicit
' フォルダ作成とブック保存を統合したメイン処理
Sub SaveWorkbookToNewFolder()
Dim targetPath As String
Dim fileName As String
Dim fso As Object
' 保存先の親パスとファイル名を定義
targetPath = "C:\Users\Public\Documents\SalesReports\2023\October"
fileName = "Report_" & Format(Date, "yyyymmdd") & ".xlsx"
Set fso = CreateObject("Scripting.FileSystemObject")
' フォルダが存在しなければ作成する
If Not fso.FolderExists(targetPath) Then
CreateFolderRecursive fso, targetPath
End If
' ブックを保存(既存ファイルがある場合は上書き確認を抑制)
Application.DisplayAlerts = False
On Error Resume Next
ThisWorkbook.SaveAs Filename:=targetPath & "\" & fileName
If Err.Number <> 0 Then
MsgBox "保存に失敗しました:" & Err.Description, vbCritical
Else
MsgBox "保存が完了しました:" & vbCrLf & targetPath & "\" & fileName, vbInformation
End If
On Error GoTo 0
Application.DisplayAlerts = True
Set fso = Nothing
End Sub
' 再帰的にフォルダを作成する関数
Sub CreateFolderRecursive(fso As Object, path As String)
' 親フォルダが存在しない場合は、親フォルダから先に作成する
If Not fso.FolderExists(fso.GetParentFolderName(path)) Then
CreateFolderRecursive fso, fso.GetParentFolderName(path)
End If
' 対象フォルダを作成
fso.CreateFolder path
End Sub
詳細解説:コードのポイント
このコードの要点は「再帰呼び出し」の活用にあります。「CreateFolderRecursive」関数は、自分自身を呼び出すことで、パスの最上階層から一つずつ「フォルダが存在するか?」を検証します。
例えば「A\B\C」というパスを指定した場合、まず「A」があるかを確認し、なければ作成。次に「A\B」を確認し、なければ作成。最後に「A\B\C」を作成するというステップを踏みます。これにより、どのような複雑なパスであっても「パスが見つかりません」というエラーを完全に回避できます。
また、保存時の「Application.DisplayAlerts = False」は必須です。既存ファイルが存在する場合、Excelは「上書きしますか?」という警告ダイアログを表示しますが、自動化処理中にこれが立ち上がるとマクロが停止してしまいます。この設定で警告を無効化し、スムーズな保存を実現します。
実務アドバイス:プロの現場で意識すべきこと
1.パスの末尾文字の管理
フォルダパスを取得する際、末尾に「\」が含まれている場合といない場合があります。FSOのメソッドはこれに柔軟に対応しますが、手動で文字列結合を行う場合は必ず「If Right(path, 1) <> “\” Then path = path & “\”」のようなチェックを入れ、パスの整合性を保つ癖をつけましょう。
2.ネットワークドライブへの対応
共有サーバー(UNCパス:\\ServerName\Folder…)に保存する場合、権限の問題でフォルダ作成ができないことがあります。コードには必ずエラーハンドリング(On Error GoTo…)を組み込み、フォルダが作成できなかった際の通知処理を実装してください。
3.命名規則の動的生成
ファイル名に「日付」や「担当者名」を動的に含める場合、ファイル名に使用できない文字(\ / : * ? ” < > |)が含まれていないか、事前に置換処理を挟むことが推奨されます。
4.パフォーマンスの考慮
大量のファイルを一度に保存する場合、毎回FSOをインスタンス化するのは非効率です。ループ処理の中で呼び出す場合は、FSO変数をループの外側で定義し、使い回すようにしましょう。
まとめ
フォルダの自動生成は、VBAによる業務効率化における「基礎体力」のようなものです。一度この再帰的なフォルダ作成のロジックを習得してしまえば、ファイル整理、バックアップ、定型レポートの出力など、あらゆる業務プロセスを劇的に簡略化できます。
今回紹介した「FileSystemObject」と「再帰処理」の組み合わせは、非常に堅牢で、メンテナンス性も高い手法です。まずはご自身の環境でこのコードを走らせ、階層構造が自動で生成される心地よさを体感してください。VBAのスキルアップは、こうした「エラーを未然に防ぐ小さな工夫」の積み重ねによって成し遂げられます。明日からの業務で、ぜひ活用してみてください。
