TL;DR —
MkDirは1 階層のフォルダーを作るのであって、パスを作るのではありません。C:\A\Bがまだ存在しなければMkDir "C:\A\B\C"はerror 76を発生させ、すでに存在するフォルダーに 対するMkDirはerror 75を発生させます — 無言の no-op ではありません。「このフォルダーを作る」は 実際には「足りない階層をすべて、しかも欠けている場所にだけ作る」ことなのです。
Sub MakeReportsFolder()
MkDir "C:\Reports" ' C:\ が存在し、かつ C:\Reports が存在しないときだけ動く
MkDir "C:\Reports\2026\Q1" ' error 76 — 親の C:\Reports\2026 がまだ存在しない
End Sub
MkDir は VBA でいちばん単純なステートメントに見えます — キーワードひとつ、パスひとつ。厄介なのは、
それが名前の示唆するよりずっと少ないことしかしない点です。パスを作るのではなく、親がすでに
そこになければならない単一のディレクトリを作ります。そして、すでに存在するフォルダーを大目に見る
こともありません — エラーで止まります。どちらの驚きも同じ根から来ています。MkDir は 1 階層の
操作であり、あらゆる堅牢な「フォルダーを作る」ルーチンは、その制限を軸に組み立てられているのです。
この記事で学べること
- 考え方の軸 —
MkDirは1 階層を作るのであって、パスを作るのではない - 入れ子のパスが
error 76を発生させる理由、そしてFileSystemObject.CreateFolderもまた再帰 しない理由 - 既存のフォルダーに対する
MkDirがerror 75を発生させる理由 — そしてそれを安全な「存在を 保証する」に変えるチェック - フルパスを 1 階層ずつ作る、存在ガード付きのループ
- 裸の
MkDir "Reports"がブックのフォルダーではなくCurDirの下に着地する理由 - 無人マクロのための安全な「フォルダーがなければ作る」パターン
考え方の軸:MkDir は 1 階層を作り、パスは作らない
鍵となる洞察は、MkDir がすでに存在していなければならないフォルダーの中に、単一の
ディレクトリエントリを作るということです。これは、コマンドプロンプトで古い非再帰的な振る舞いの
md を打つのとちょうど同じです — 親にひとつの子を加え、その親がそこにあることを前提とします。
MkDir "C:\Reports"—C:\の中にReportsを作る。C:\は存在するので問題なし。MkDir "C:\Reports\2026"—C:\Reportsの中に2026を作る。C:\Reportsがすでに存在する ときにのみ動く。MkDir "C:\Reports\2026\Q1"— 先にC:\Reports\2026が存在する必要があり、なければ失敗する。
いったん MkDir を「既存の親にひとつの子を加える」ものとして見れば、その 2 つの有名なエラーは
もう驚きではなくなります — どちらも、その前提が破られる 2 通りにすぎないのです。親がない、あるいは
子がすでにある。
error 76:MkDir は入れ子のパスを作れない(CreateFolder も同じ)
中間のフォルダーが欠けている、1 階層より深いパスに MkDir を向けると、止まります。
MkDir "C:\Reports\2026\Q1" ' error 76 — C:\Reports\2026 が欠けていれば「パスが見つかりません」
広く知られた対処法 — 「FileSystemObject を使えばいい」 — は、これを解決しません。CreateFolder
もまた1 階層の操作であり、親が欠けていれば MkDir とまったく同じように「パスが見つかりません」を
発生させます。
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")
fso.CreateFolder "C:\Reports\2026\Q1" ' C:\Reports\2026 が存在しなければこれも失敗する
どちらの組み込みも、中間のフォルダーを代わりに作ってはくれません。だから深いパスを組み立てるのは、
本質的にループになります。パスを区切り文字で分割し、各階層を上から順に作り、すでに存在するものは
飛ばすのです。組み込みの VBA に mkdir -p を行う単一の呼び出しはありません — 自分で書きます。その
ループはほんの数行(下記)で、いったん手に入れれば、入れ子の作成は解決済みの問題になります。
error 75:既存フォルダーへの MkDir は no-op ではない
2 つ目の驚きは、フォルダーがすでに存在すると MkDir が失敗することです — 静かに成功したりは
しません。
MkDir "C:\Reports" ' 初回:作成される
MkDir "C:\Reports" ' 2 回目:error 75 — 「パス/ファイル アクセス エラー」
これが、「一度は動いた」マクロが 2 回目の実行でクラッシュする理由です。MkDir は冪等ではないので、
無条件に呼ぶのはバグです。直し方は、Dir のフォルダー対応の形か FolderExists
で、まずチェックすることです。
If Dir("C:\Reports", vbDirectory) = "" Then MkDir "C:\Reports" ' ないときだけ作る
vbDirectory フラグは Dir をフォルダーに一致させるので、
Dir(path, vbDirectory) = "" は「このフォルダーは存在しない」を意味します。MkDir をそのテストで
包めば、ステートメントは安全な存在保証になります — 初回にフォルダーを作り、それ以降の毎回は
何もしません。より明快な代替は fso.FolderExists(path) で、あいまいさなく読め、
Dir ガイドで説明した共有の Dir カーソルに一切触れません。
パターン:フルパスを 1 階層ずつ作る
2 つの制限を合わせると、入れ子のパスを確実に作るルーチンはこうなります — VBA が与えてくれない
mkdir -p です。ルートからパスをたどり、欠けている各階層を作ります。
Sub EnsurePath(ByVal fullPath As String)
Dim parts() As String, build As String, i As Long
parts = Split(fullPath, "\")
build = parts(0) ' ドライブ、例 "C:"
For i = 1 To UBound(parts)
build = build & "\" & parts(i)
If Dir(build, vbDirectory) = "" Then MkDir build ' この階層がなければ作る
Next i
End Sub
EnsurePath "C:\Reports\2026\Q1" を呼ぶと、Reports、次に 2026、次に Q1 を作り、すでに存在する
ものはすべて飛ばして、error 75 も 76 も決して発生させません。これは、ほぼすべての実運用の
「フォルダーを作る」ヘルパーが取る形です — 両方の組み込みがそれを強いるからです。
For ループと Split が歩く仕事を、
Dir(..., vbDirectory) ガードが安全の仕事をします。
裸のフォルダー名が間違った場所に着地する理由
MkDir は相対パス — ドライブも先頭の \ もない名前 — を受け付けます。そしてそこに、微妙な
バグが潜んでいます。
MkDir "Reports" ' これはどこに行く? 必ずしもブックの隣ではない
相対パスは CurDir、Excel のカレントディレクトリに対して解決されます — それはたいていブックが
保存されているフォルダーではなく、ファイルを開くダイアログが新しい場所を指すたびに変わります。
だから MkDir "Reports" は、ある日はドキュメントに、翌日は別のどこかにフォルダーを作りかねません。
信頼できる習慣は、ThisWorkbook.Path から絶対パスを組み立てることです。
MkDir ThisWorkbook.Path & "\Reports" ' つねにこのブックの隣
それは CurDir ガイドの主題そのものです。MkDir、RmDir、
そしてファイルオープンにおける相対パスは、すべてあなたが制御できない作業ディレクトリに対して解決
されます。だから、代わりにすべてのパスを ThisWorkbook.Path に固定しましょう。
正直な結論:1 階層、ガード付き、絶対パス
MkDir はフォルダーを作るための正しい道具です — それが実際に何をするかを尊重する限りにおいて。
4 つのルール。
- 1 階層を作る → 入れ子のパスには 1 階層ずつのループが要る。
MkDirもCreateFolderもmkdir -pはしない。 - 冪等ではない →
If Dir(path, vbDirectory) = "" Then(またはFolderExists)でガードする。 さもないと 2 回目の実行でerror 75になる。 - 親がなければ
error 76→ 葉からではなく、ルートから下へ組み立てる。 - 相対名は
CurDirに従う →ThisWorkbook.Pathから絶対パスを組み立て、 フォルダーがつねに思ったところに着地するようにする。
スクリプトの中で MkDir を 2 回書いていると気づいた瞬間 — 一度は作るため、一度は「念のため」 — その
両方をガード付きループに置き換えましょう。そのひとつのヘルパーが、error 75、error 76、そして
間違ったフォルダーのバグを、一挙に取り除きます。
ExcelMaster の活用
フォルダーを安全に作るとは、MkDir が1 つの階層しか作らないこと、親が欠けている(76)か
フォルダーがすでに存在する(75)とエラーになること、そして裸の名前がブックではなく CurDir に
従うことを覚えておくこと — ただフォルダーを作るだけに見えるステートメントを取り巻く、4 つの罠です。
ExcelMaster は、止まらない
「フォルダーを作る」ルーチンを書きます。ジョブを説明すれば — 「各レポートを日付付きのサブフォルダーに
保存して」、あるいは「出力ツリーがなければ組み立てて」 — 存在ガード付きで 1 階層ずつのループを、
ThisWorkbook.Path に固定して生成します。だからパスは一度だけ作られ、再実行で
error 75 を決して発生させません。あなたはほしいフォルダーを説明するだけ。足りない階層をすべて作り、
残りは飛ばすコードを書くのは、それがやります。
よくある質問
VBA でフォルダーを作るには?
MkDir ステートメントにフルパスを渡します:MkDir "C:\Reports"。すでに存在していなければならない
親の中に、1 階層のフォルダーを作ります。再実行で失敗しないようガードしましょう —
If Dir("C:\Reports", vbDirectory) = "" Then MkDir "C:\Reports" — MkDir はフォルダーがすでに存在
すると、何もしない代わりに error 75 を発生させるからです。
VBA の MkDir が error 76 Path not found になるのはなぜですか?
MkDir が1 つの階層しか作らず、パスの中の親フォルダーが存在しないからです。C:\Reports\2026 が
欠けていれば、MkDir "C:\Reports\2026\Q1" は error 76 で失敗します。MkDir は中間のフォルダーを
作らず、FileSystemObject.CreateFolder も同じです。深いパスを組み立てるには、ループの中で各階層を
ルートから下へ作り、各 MkDir の前に Dir(level, vbDirectory) をチェックしましょう。
フォルダーがまだ存在しないときだけ作るには?
vbDirectory フラグでまずチェックします:If Dir("C:\Reports", vbDirectory) = "" Then MkDir "C:\Reports"。
Dir(path, vbDirectory) はフォルダーが存在すればその名前を、なければ空文字列を返すので、MkDir は
フォルダーがないときだけ実行されます。より明快な代替は FileSystemObject の fso.FolderExists(path)
で、あいまいさなく読め、Dir カーソルを乱しません。
VBA で入れ子のフォルダーを一度に作るには?
組み込みの VBA に単一の mkdir -p 呼び出しはありません — MkDir も FileSystemObject.CreateFolder
も 1 階層しか作りません。パスを "\" で分割し、各階層を上から順に作ります。ドライブから始め、一度に
ひとつのセグメントを付け足し、Dir(build, vbDirectory) が欠けていると報告する各セグメントを MkDir
します。そのループは Reports、次に 2026、次に Q1 を作り、すでに存在するものはすべて飛ばします。
相対パスを使うと MkDir はどこにフォルダーを作りますか?
MkDir "Reports" のような相対パスは、CurDir、Excel のカレントディレクトリに対して解決されます —
それはたいていブックのフォルダーではなく、ファイルを開くダイアログが別の場所を指すと変わりえます。
毎回ブックの隣にフォルダーを作るには、絶対パスを組み立てましょう:MkDir ThisWorkbook.Path & "\Reports"。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-23。
関連ガイド: VBA RmDir · VBA CurDir · VBA Check If File Exists · VBA Dir · VBA FileSystemObject
