銀河鉄道

【VBA】フォルダを作る|MkDir(フォルダがすでに存在していればエラーになる)

サムネイル
[VBA]Make Directory MkDir
MkDirは
Make Directory

フォルダのことを「ディレクトリ」とも呼ぶ

MkDir でフォルダ作成

フォルダ作成後、フォルダのパスを返す

引数 path の中身は、ThisWorkbook.Path など

チェーン版|親階層までチェックする

' Prefer atomic create over pre-check|事前チェックより原子的作成を優先
Public Function MakeFolderPathChain( _
		ByVal basePath As String, _
		ByVal folderName As String) As String

	' "\" を使う(ロケール非依存)|Use "\" consistently (locale-agnostic)
	Dim folderPath As String
	folderPath = basePath & "\" & folderName

	' 親フォルダを含めて確実に作成|Ensure parent chain exists
	Call EnsureFolderChain(folderPath)

	MakeFolderPathChain = folderPath
End Function

' Create all missing levels safely|足りない階層を安全に作成
Private Sub EnsureFolderChain(ByVal fullPath As String)
	Dim parts() As String
	Dim i As Long
	Dim cur As String

	parts = Split(fullPath, "\")
	' ドライブレター対応(C: など)|Handle drive prefix
	If InStr(parts(0), ":") > 0 Then
		cur = parts(0)
		i = 1
	Else
		cur = parts(0)
		i = 1
	End If

	For i = i To UBound(parts)
		If Len(cur) > 0 Then
			cur = cur & "\" & parts(i)
		Else
			cur = parts(i)
		End If

		' 事前チェック不要:作ってみて、既存エラー(75)だけ無視
		On Error Resume Next
		MkDir cur
		Select Case Err.Number
			Case 0
				' 作成成功|Created
			Case 75
				' 既に存在|Already exists → ignore
			Case Else
				Dim em As String
				em = "Failed to create folder: " & cur & " (Err " & Err.Number & ")"
				On Error GoTo 0
				Err.Raise vbObjectError + 513, "EnsureFolderChain", em
		End Select
		On Error GoTo 0
	Next i
End Sub

簡易版(親階層のチェックなし)

' Single-level create (simple)|単段だけ作る簡易版
' 親が存在する前提。既存(Err 75)は握る。
Public Function MakeFolderPathSimple( _
		ByVal basePath As String, _
		ByVal folderName As String) As String

	Dim folderPath As String
	folderPath = basePath & "\" & folderName

	On Error Resume Next
	MkDir folderPath
	Select Case Err.Number
		Case 0, 75
			' 作成 or 既存 → OK
		Case Else
			Dim em As String
			em = "Failed to create: " & folderPath & " (Err " & Err.Number & ")"
			On Error GoTo 0
			Err.Raise vbObjectError + 513, "MakeFolderPathSimple", em
	End Select
	On Error GoTo 0

	MakeFolderPathSimple = folderPath
End Function

パスを返す目的は、メッセージ表示に使ったりとか、フォルダを開いたりとか

フォルダの存在確認するより“作ってみてエラーが出るか”を探る

MkDir はフォルダ存在していれば、Err.Number=75(既に存在)を返す

Trying the create and handling errors beats pre-checks under race.

  • Dirで存在確認→MkDirより、MkDir→Errで判断の方がレース条件|race conditionに強い。
  • 理由Dir の結果は瞬間の写真に過ぎず、その直後に他プロセスがフォルダ作成すると競合が起こる
  • Key pointMkDir 後に Err.Number=75だけを無視し、他のエラー(76 など)は通報。親階層は段階的に作る

親階層のチェックをするか、しないか

  • 親階層までチェックする場合
    • basePath が未作成の可能性がある、または folderNamereports\2025\10 のような階層(サブフォルダ連結)が含まれる場合
  • 簡易版の場合
    • 親フォルダは必ず存在し、作るのは末端1段だけという前提の場合
    • (逆にチェーン版は過剰になる)

なぜ?

  • MkDir は一階層しか作れない(親がなければ Err 76: Path not found)。
  • basePath が存在しない可能性や、folderName\ を含む(= 複数階層をまとめて作りたい)ケースでは、手前から順に作るほうが安全
  • 逆に、簡易版でも十分な場合は、チェーンは過剰になる

判断の目安

  1. basePath の存在が保証されてる?
    • Yes → 次へ
    • No → EnsureFolderChain を使う
  2. folderName にバックスラッシュが含まれる?("a\b\c"
    • Yes → EnsureFolderChain を使う
    • No → 単段作成パターンでOK
Prefer “try-create + handle (Err 75)” over “pre-check + create.”

著者

author
月うさぎ

編集後記:
この記事の内容がベストではないかもしれません。

記事一覧