TL;DR — 相対パス(
"Reports"のような、ドライブのない名前)は、CurDir、Excel の カレントディレクトリに対して解決されます — それはブックのフォルダーではなく、ファイルを開く ダイアログが新しい場所を指すたびに変わります。だからMkDir"Reports"やOpen "data.csv"は、実行のたびに別の場所に着地しかねません。すべてのパスをThisWorkbook.Pathに 固定しましょう。
Sub WhereDoesThisGo()
MkDir "Reports" ' CurDir の下に作られる — たいていブックの隣ではない
MkDir ThisWorkbook.Path & "\Reports" ' 毎回、この「ブック」自身の隣に作られる
End Sub
これは、ひと群れの混乱した報告の裏にあるバグです。「マクロがフォルダーを間違った場所に作った」
「ファイルをドキュメントに保存した」「昨日は動いたのに今日は動かない」。どれも偶然ではありません。
すべては、人々が疑おうとも思わないひとつの事実にたどり着きます — VBA の相対パスは、Excel があなたの
代わりに管理する作業ディレクトリに対して解決されるのであり、そのディレクトリはあなたが思い込んで
いる場所ではない、ということです。CurDir を理解すれば、それらのバグのひとつひとつが、たった一つの
習慣で防げるようになります。
この記事で学べること
- 考え方の軸 — 相対パスは
CurDirに対して解決されるまで何の意味も持たない CurDirがThisWorkbook.Pathでない理由、そして実際にどこを指すか- ファイルを開くダイアログが、マクロの途中で
CurDirを無言で変える仕組み ChDirがドライブを変えられない理由、そしてChDriveが別のステートメントである理由- 一度も保存されていないブックでは
ThisWorkbook.Pathが空になる理由 - 間違ったフォルダーのバグをまるごと取り除く、たった一つの習慣
考え方の軸:相対パスは CurDir に対して解決される
鍵となる洞察は、VBA には 2 種類のパスがあり、両者はまったく違う振る舞いをする、ということです。
- 絶対パス — ドライブまたはルートで始まる:
"C:\Reports\March.xlsx"。ちょうどひとつの場所を 意味する。 - 相対パス — ドライブなし、先頭の
\なし:"Reports"や"data\in.csv"。「カレント ディレクトリからの相対」を意味し、VBA が残りをCurDirから埋める。
CurDir は、その作業ディレクトリを返す関数です — 現在のドライブなら CurDir、特定のドライブなら
CurDir("D")。パスを取るすべてのステートメント — MkDir、
RmDir、Open、Kill、Name、Dir — は、相対パスを
CurDir に対して解決します。だから「フォルダーはどこへ行った?」という問いは、実際には「ステート
メントが走った瞬間、CurDir は何だったか?」であり — それは聞こえるよりずっと自明でない問いなのです。
CurDir は ThisWorkbook.Path ではない
すべての根にある誤解はこれです。人々は「カレントディレクトリ」がブックの置かれているフォルダーだと 思い込みます。違います。両者は無関係な 2 つの値です。
Debug.Print CurDir ' Excel の作業ディレクトリ — たいてい C:\Users\You\Documents
Debug.Print ThisWorkbook.Path ' この「ブック」が保存されている場所 — 例 D:\Projects\2026
CurDir は、Windows が起動時に Excel へ渡したもの(しばしばあなたのドキュメントフォルダー)として
始まり、ブックをどこから開いたかとは何のつながりもありません。だから MkDir "Reports" は
ファイルの隣にフォルダーを作りません — CurDir の下に作り、それはどこでもありえます。対照的に
ThisWorkbook.Path は、コードを実行しているブックを含むフォルダーをつねに指します。「自分のブックの
隣」を意味するときはいつでも、ほしいのはそのプロパティです — 決して CurDir ではありません。
ファイルを開くダイアログが CurDir を無言で変える
間違ったフォルダーのバグが間欠的である理由 — 昨日は平気、今日は壊れる — は、CurDir がじっと
していないからです。ユーザー(またはあなた自身のコード)がファイルダイアログでフォルダーを参照する
たびに、Windows がそれを更新します。
Dim f As Variant
f = Application.GetOpenFilename ' ユーザーが D:\Client\Inbox まで参照してファイルを選ぶ
' CurDir はいま D:\Client\Inbox — 目に見えず動いた
MkDir "Reports" ' D:\Client\Inbox\Reports を作る、意図した場所ではない
あなたのコードは「ディレクトリを変えろ」とは一言も言っていないのに、ダイアログがそれを設定したせいで
CurDir は動きました。その時点以降のどんな相対パスも、新しい場所に対して解決されます。これが、同じ
マクロが、ユーザーが 5 分前に何をクリックしたかによって別のフォルダーへ書き込む理由です — 本当に目に
見えない依存であり、CurDir が動く部品だと知らない限り、答えようのないサポートチケットになります。
ChDir はフォルダーを変える — ただしドライブは変えない
もし作業ディレクトリを意図して設定したいなら、ChDir がそのステートメントです — が、ほとんど
誰もが引っかかる罠があります。ChDir は現在のフォルダーを変えるのであって、現在のドライブは
変えません。
ChDir "D:\Data" ' D: の既定フォルダーを \Data に設定する — でもまだドライブ C: にいる
CurDir ' なお C:\... を返す — ドライブは変わっていない
実際に別のドライブへ移るには、先に ChDrive が要り、それは別のステートメントです。
ChDrive "D" ' 現在のドライブを D: に切り替える
ChDir "D:\Data" ' これで D: 上のフォルダーを設定する
この分割 — ドライブに 1 つ、フォルダーにもう 1 つのステートメント — は、各ドライブが自分のカレント ディレクトリを覚えていた DOS の名残です。それはまさに、「作業ディレクトリをただ設定する」をもろく する類いの驚きです。そしてそれは本当の直し方を指し示します。作業ディレクトリなど、そもそも管理しない ことです。
バグをまるごと取り除く習慣
相対パスを一切使わなければ、上のあらゆる間違ったフォルダーのバグは消えます。ThisWorkbook.Path から
絶対パスを組み立て、それをすべてのファイルステートメントに手渡しましょう。
Dim base As String
base = ThisWorkbook.Path & Application.PathSeparator ' 例 "D:\Projects\2026\"
MkDir base & "Reports" ' つねにブックの隣
Open base & "data.csv" For Output As #1 ' 同じアンカー、CurDir 依存なし
2 つの細部が、これを堅牢にします。ハードコードした "\" ではなく Application.PathSeparator を使って
コードが区切り文字を決め打ちしないようにし、末尾の区切り文字に気を配って、うっかり ...2026Reports を
作らないようにすることです。すべてのパスを ThisWorkbook.Path に固定すれば、CurDir は無関係に
なります — ダイアログがそれをどこへ押しやろうと、あなたのフォルダーは意図した場所にきっちり着地します。
ガードすべきエッジケースがひとつ。ThisWorkbook.Path は、一度も保存されていないブックでは空文字列
です。マクロが最初の保存より前に走りうるなら、If ThisWorkbook.Path = "" Then をチェックして、何も
ないところから壊れたパスを組み立てる代わりに、場所の入力を促しましょう。
正直な結論:CurDir ではなく ThisWorkbook.Path に固定する
CurDir は、それに依存するのをやめられるように、まさに理解しておく価値があります。4 つのルール。
- 相対パスは
CurDirに従う → そしてCurDirは、ブックのフォルダーではなく、Excel の 移ろいやすい作業ディレクトリである。 - ファイルを開くダイアログが
CurDirを動かす → だから相対パスは間欠的に間違う。作業ディレクトリが 置いたままの場所にあると決して信じない。 ChDirはドライブを変えない → 先にChDriveが要る。どちらも、持たなくてよい状態を管理している 印。ThisWorkbook.Pathに固定する →Application.PathSeparatorで絶対パスを組み立て、未保存ブックの ケースをガードすれば、間違ったフォルダーのバグは永遠に消える。
これが、フォルダーの道具たちを結ぶ糸です。MkDir と RmDir
は、あなたが手渡すパスと同じだけしか信頼できず、相対パスはあなたの運命を CurDir に委ねます。
ThisWorkbook.Path から組み立てた絶対パスを与えれば、両方のステートメントは、毎回、あなたの期待
どおりに動きます。
ExcelMaster の活用
パスを正しく扱うとは、CurDir がブックのフォルダーでないこと、ファイルを開くダイアログが警告
なしにそれを動かすこと、ChDir がドライブを変えられないこと、そして ThisWorkbook.Path はブックが
保存されるまで空であることを知っていることです — 「フォルダーを間違った場所に作った」というあらゆる
報告の裏にある、4 つの罠です。
ExcelMaster は、意図したところに
着地するパスを書きます。ジョブを説明すれば — 「エクスポートをこのブックの隣に保存して」、あるいは
「出力フォルダーをプロジェクトディレクトリに組み立てて」 — Application.PathSeparator を使って
ThisWorkbook.Path に固定した絶対パスを生成し、CurDir に依存する相対パスは決して使わず、未保存の
ケースをガードします。あなたはファイルがどこへ行くべきかを説明するだけ。毎回そこに置くパスを書くのは、
それがやります。
よくある質問
VBA で CurDir は何を返しますか?
CurDir は Excel のカレントディレクトリ — 相対パスが解決される先のフォルダー — を返します。
CurDir は現在のドライブのディレクトリを、CurDir("D") はドライブ D のそれを返します。たいていは
Excel が起動したときに Windows が設定したもの(しばしばあなたのドキュメントフォルダー)であり、ブックが
保存されている場所とは何のつながりもありません。だから「自分のファイルの隣」の意味で使っては
いけません。
VBA マクロがフォルダーを作る、またはファイルを保存する場所が間違うのはなぜですか?
相対パスを使い、VBA がそれをブックのフォルダーではなく CurDir に対して解決したからです。CurDir
は Excel の作業ディレクトリで、ファイルを開くダイアログがそれを無言で変えるので、同じ相対パスが実行の
たびに別のフォルダーに着地します。ThisWorkbook.Path から絶対パスを組み立てれば —
ThisWorkbook.Path & "\" & "Reports" — 場所は CurDir に依存しなくなります。
CurDir と ThisWorkbook.Path の違いは何ですか?
CurDir は Excel の移ろいやすい作業ディレクトリ — 相対パスが解決される場所で、どんなファイル
ダイアログでも変えられます。ThisWorkbook.Path は、コードを実行しているブックが保存されている
フォルダーで、動きません。「このブックの隣」を意味するときは、つねに ThisWorkbook.Path を使いま
しょう。CurDir を使うのは、本当に作業ディレクトリがほしいときだけで、それはまれです。
VBA で ChDir がドライブを変えないのはなぜですか?
ChDir は現在のフォルダーだけを変え、現在のドライブは変えないからです — 各ドライブが自分の
カレントディレクトリを保っていた DOS の名残です。C: にいるときの ChDir "D:\Data" は、D: の既定
フォルダーを設定しますが、あなたは C: に残ります。ドライブを切り替えるには、先に ChDrive "D" を
呼び、それから ChDir "D:\Data" です。実務では、作業ディレクトリを丸ごと避けて絶対パスを使うほうが
簡単です。
ThisWorkbook.Path が空になるのはなぜですか?
ThisWorkbook.Path は、ブックが一度も保存されていないとき空文字列を返します — 未保存のブックには
まだフォルダーがありません。マクロが最初の保存より前に走る可能性があるなら、If ThisWorkbook.Path = "" Then
をチェックし、空文字列からパスを組み立てる(それは CurDir に対して解決される相対パスを生む)代わりに、
(Application.GetSaveAsFilename で)ユーザーに場所を尋ねましょう。
検証環境
検証環境: Excel 365 (Windows 11), VBA 7.1 — 最終確認 2026-08-23。
関連ガイド: VBA MkDir · VBA RmDir · VBA Dir · VBA Open Workbook · VBA Check If File Exists
