🚀The world's best VBA AI has evolved. ExcelMaster is now an autonomous Agent.Read more →
Back to Blog

VBA CurDir & ChDir in Excel — 相対パスが間違ったフォルダーに着地する理由

|

VBA CurDir & ChDir in Excel — 相対パスが間違ったフォルダーに着地する理由

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 に対して解決されるまで何の意味も持たない
  • CurDirThisWorkbook.Pathない理由、そして実際にどこを指すか
  • ファイルを開くダイアログが、マクロの途中で CurDir無言で変える仕組み
  • ChDirドライブを変えられない理由、そして ChDrive が別のステートメントである理由
  • 一度も保存されていないブックでは ThisWorkbook.Path が空になる理由
  • 間違ったフォルダーのバグをまるごと取り除く、たった一つの習慣

考え方の軸:相対パスは CurDir に対して解決される

鍵となる洞察は、VBA には 2 種類のパスがあり、両者はまったく違う振る舞いをする、ということです。

  • 絶対パス — ドライブまたはルートで始まる:"C:\Reports\March.xlsx"。ちょうどひとつの場所を 意味する。
  • 相対パス — ドライブなし、先頭の \ なし:"Reports""data\in.csv"。「カレント ディレクトリからの相対」を意味し、VBA が残りを CurDir から埋める。

CurDir は、その作業ディレクトリを返す関数です — 現在のドライブなら CurDir、特定のドライブなら CurDir("D")。パスを取るすべてのステートメント — MkDirRmDirOpenKillNameDir — は、相対パスを 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 で絶対パスを組み立て、未保存ブックの ケースをガードすれば、間違ったフォルダーのバグは永遠に消える。

これが、フォルダーの道具たちを結ぶ糸です。MkDirRmDir は、あなたが手渡すパスと同じだけしか信頼できず、相対パスはあなたの運命を 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