絶対パスと相対パスを理解する
マクロに慣れてくるとほかのファイルを開いて作業をする機会が増えてきます。
別ファイルを開く時には対象のファイルまでのパスを用意する事になります。
パスにも種類があります。それぞれの使い方、メリットやデメリットがあります。
大きく分けるとこの2つを勉強しておけば問題ないです。
- 絶対パス
- 相対パス
2つの要素で大半の事例はカバーできるのですが絶対パス、相対パスを勉強する時に一緒に勉強してほしい内容があります。
カレントディレクトリです。カレントディレクトリが理解出来てないと相対パスを使いこなすことはできません。
今回は絶対パスと相対パスと一緒にカレントディレクトリを勉強していきます。
最後に私が使っているコードの書き方を紹介します。
すっきりしたコードが書けるようになります。
そのためには絶対パスと相対パス、カレントディレクトリを理解していただく必要があります。
画像やリスト、コードを使って分かりやすく解説していきますのでご安心ください。
関連情報
ファイルパスをうまく設定できればクラウド環境にもアクセスすることは可能です。
SharePointの環境にもExcelVBAならアクセスすることができます。
この本で勉強しました
「やりたい事は明確なんだけどコードに置き換えられない」と思った事はありませんか?
ワークブック間の処理は特に多くの方から「コードが思いつかない」という問い合せをいただきます。
初心者の頃私はこの本で勉強しました。コードが思いつかない時は事例を見て参考にすると良いです。
いつでも見れる環境に1冊用意しておくと非常に便利な書籍ですよ。
私が選んだ書籍の他にも良い本は沢山あります。AmazonのExcelVBA関連の書籍から高評価な書籍を選んでおきました。
マクロは電子書籍で勉強するのがベスト
Kindleストアのリンクを用意しておきます。PCの中に事例のライブラリーを構築する事が出来ますよ。
ファイルにアクセスする為のパスについて
パスについて見た目で理解しましょう。
絶対パスを使ってフルパスとパスとファイル名を表現しました。
諸説ありますが今回はA.xlsmの前のバックスラッシュまでをパスとします。
バックスラッシュは¥マークでもスラッシュでもOKです。
ただしコード内に色んな記号が乱立すると見にくいので記号は統一させて使う様にしてください。
絶対パスというキーワードを先に書いてしまいましたがこの後説明しますのでご安心ください。
これをふまえて事例を見ていきましょう。
事例で解説
デスクトップに1つのフォルダを用意します。「黄」という名前のフォルダにします。
続いて「黄」フォルダの中に「青」フォルダと「緑」フォルダを用意します。
「黄」フォルダ内にA.xlsm、「青」フォルダ内にB.xlsm、「緑」フォルダ内にC.xlsmを用意します。
各.xlsmを使って絶対パスと相対パスを書いてみます。
絶対パス
個人毎に設定した固有の情報を含め全部を書き出すのが絶対パスです。
デフォルトの時は***に個人で設定したユーザー名が入ることになります。
コピーして使える様にリストにしておきます。
番号 | ファイル名 | フルパス |
---|---|---|
1 | A.xlsm | C:\Users\***\Desktop\黄\A.xlsm |
2 | B.xlsm | C:\Users\***\Desktop\黄\青\B.xlsm |
3 | C.xlsm | C:\Users\***\Desktop\黄\緑\C.xlsm |
コードはこちらです。
Sub 絶対パス()
'B.xlsmの標準モジュールにコードを書いて実行しています
'1、絶対パスでA.xlsmを開く
Workbooks.Open "C:\Users\***\Desktop\黄\A.xlsm"
End Sub
Openメソッドについてはこちらの記事をご覧ください。
メリット
フルパス(パスとファイル名)を全部書いているので見た目で分かりやすいです。
加えて作りやすいです。理由は相対パスに比べて何も考えず全部書けば良いからです。
ほとんどメリットしかないようにも見えますがデメリットもあります。
デメリット
リスト内の***にはユーザーが個人で設定した名前が入る事が多いです。
ここが固有の情報になる為他者のPCでは認識されなくなりエラーになります。
メリットに引けをとらないレベルのデメリットなので無視できません。
カレントディレクトリ
相対パスに入る前にカレントディレクトリについて説明します。
この意味が分かってないと相対パスをうまく使えません。よってこのタイミングで説明しています。
私はカレントディレクトリというのは「今開いているデータが居るフォルダ」の事かと思っていました。
結論を申し上げますとこの考えは間違いです。この考え方だと矛盾が生じるケースがあります。
前提としてカレントディレクトリは1つです。
前提をふまえたうえで「データを2つ開いている時」のカレントディレクトリを考えてみましょう。
開いているデータの位置をカレントディレクトリにするとカレントディレクトリが2つになってしまいます。
という事は「今開いているデータが居るフォルダ」という考え方は間違いだと分かります。
正しいカレントディレクトリの定義はこちらです。
カレントディレクトリ(英語: current directory)とは、実行中のソフトウェアなどがストレージ(外部記憶装置)のファイルシステム中で現在位置として指し示しているディレクトリのこと
Wikipedia
ざっくり言うと「ディレクトリ」=「フォルダ」です。
「既定のローカルファイルの保存場所」については以降で解説します。
カレントディレクトリは設定されています
定義を見るからにカレントディレクトリは別に設定されているような感じがします。探しましょう。
エクセルのファイルタブをクリック→左の緑の短冊からオプションを選択してください。
Excelのオプションというダイアログボックスが展開されます。
左の短冊から「保存」を選択し「既定のローカルファイルの保存場所」を見てください。
ここがカレントディレクトリです。
デフォルトではご自身のPCのドキュメントを指しているはずです。
相対パスの起点(出発点)はここになります。
・・・と言いたいところですがこのパスはファイルの開き方によって変わります。
これは相対パスの起点が定まっていないという事を意味しています。
そんなこともあり相対パスでコードを書く時はひと手間必要です。
カレントディレクトリを一時的に変える
ChDir ThisWorkbook.Path というコードを書きましょう。
タイミングとしてはプロシージャ内で相対パスのコードが実行される前に書くと良いでしょう。
コードの実行時に.xlsmがアクティブであればこのデータが居るフォルダがカレントディレクトリになります。
ワークブックを閉じるor再度カレントディレクトリを変えるまでカレントディレクトリは継続します。
相対パス
対象の.xlsmを起点にしてアクセスしたい.xlsmまでのパスを書くのが相対パスです。
こちらもコピーして使える様にリストにしておきます。
番号 | 起点ファイル | ファイル名 | フルパス |
---|---|---|---|
1 | B.xlsm | A.xlsm | ../A.xlsm |
2 | B.xlsm | C.xlsm | ../緑/C.xlsm |
相対パスでコードを作る際はChDirでカレントディレクトリを起点にするのを忘れない様にしましょう。
続いてコードを紹介します。
Sub 相対パス()
'B.xlsmの標準モジュールにコードを書いて実行しています
'2、相対パスでA.xlsmを開く
'現状のカレントディレクトリをイミディエイトウィンドウに表示
Debug.Print CurDir
'カレントディレクトリをThisWorkbook.PathでB.xlsmが居るフォルダに変える
ChDir ThisWorkbook.Path
'カレントディレクトリが変わっているか確認
Debug.Print CurDir
'相対パスでA.xlsmを開く
Workbooks.Open "../A.xlsm"
End Sub
Debug.Print・・・のコードは必要に応じて消してください。確認用で残しているだけです。
(イミディエイトウィンドウを確認いただくとカレントディレクトリが切り替わったことが分かるので書いています)
メリット
黄フォルダをそのまま他者に渡しても他者のPCでエラーなくパスが通ります。
黄、青、緑フォルダの関係(配置)を変えなければパスと環境との差異が生まれない為です。
理由は相対パスにしたことで起点になるデータがコードを持っている.xlsmになっている為です。
このケースではB.xlsmになります。これならユーザーの情報が含まれた上流のパスをかまう必要が無いです。
デメリット
相対パスも環境次第ではうまく使えない事があります。
自分のデスクトップなどのローカル環境ではパスが繋がりますがネットワーク内ではエラーになります。
ChDir ThisWorkbook.Path でカレントディレクトリが切り替わらない様です。
ネットワーク内でパスを通す方法は以降で解説します。
カレントディレクトリの事も含めて考える必要があるので慣れないと使いにくいかもしれません。
加えて相対パス自体の考え方も理解する必要があります。
相対パスでは以下リストのようにフォルダを表現する事ができます。2つ上の階層のフォルダも指定できます。
番号 | 記号 | 説明 |
---|---|---|
1 | ./ | 同階層のフォルダ |
2 | ../ | 1つ上の階層のフォルダ |
3 | ../../ | 2つ上の階層のフォルダ |
画像で紹介した2つの事例はまず黄フォルダに向かうので../からパスが始まっていますね。
記号については冒頭で説明した通りスラッシュ、¥、バックスラッシュはどれを使っても良いです。
ただし色々な記号が混在すると見にくいので最低でもプロシージャ毎に統一させて使う様にしましょう。
私はこうやって使っています
WorkbooksオブジェクトのOpenメソッドの引数にThisWorkbook.Pathを直書きします。
そのあとで相対パスを繋げます。早速コードを紹介します。
これならネットワーク内でもパスを通すことができます。
ThisWorkbook.Path
文字通りコードを書いているワークブックのパスを用意する事ができます。
相対パスのところで紹介した ChDir ThisWorkbook.Path と結果同じ情報を用意する事ができます。
加えてネットワーク内でも問題なくパスを生成することが可能です。
ThisWorkbookプロパティはWorkbookを返します。
その後WorkbookクラスのPathプロパティでパスが返ってくるという流れです。
Workbookクラス(オブジェクト)のPathプロパティは文字列を返します。
これでフルパスの中からパスの部分だけを取り出して文字列として持つことができます。
コードはこちらです。
後半は相対パスを使っています。トータルで見てもシンプルです。1行で済んでますよね。
カレントディレクトリの事も考えなくて良いです。
Sub ハイブリ()
'B.xlsmの標準モジュールにコードを書いて実行しています
'3、ThisWorkbook.Pathと相対パスでA.xlsmを開く
Workbooks.Open ThisWorkbook.Path & "/" & "../A.xlsm"
End Sub
ThisWorkBook.PathでB.xlsmまでのパスを取得しています。
そこからは相対パスを使ってA.xlsmにアクセスします。
これでコードはスッキリかつ他者に黄フォルダごと渡してもエラーになりません。
&をうまく使ってパスを通す
ThisWorkbook.Path と相対パスをつなぐスラッシュを忘れない様にしてください。
分かりやすい様に連結演算子の&を2つ並べて / を書いておきました。
繰り返しになりますがつなぎの記号はスラッシュでもバックスラッシュでも\でも良いです。
決まりとしては1つのプロシージャ内では統一する様にしましょう。可読性が上がります。
連結演算子については以下関連記事をご覧ください。
比較演算子の記事に見えますが&(アンパサンド)についても記事を用意しています。
&(アンパサンド)についてVBAで文字列を比較Like演算子とワイルドカードで完全/部分一致を確認
まとめ
絶対パスと相対パスについて解説してみました。勉強していくとパスも奥が深いですよね。
当時の私の事を思い出してみるとカレントディレクトリが何かが分かると理解が進んだ印象があります。
まずはカレントディレクトリについて理解してから絶対パスと相対パスを書いてみてください。
最後はThisWorkBook.Pathで締めましょう。これでパスに対する理解が深まります。試してみてください。
絶対パス、相対パスはDir関数との相性が良いです
絶対パス、相対パスが理解できる様になったら以下記事も読んでほしいです。
Dir関数や絶対パス、相対パス、ThisWorkbookオブジェクトは一連の枠組みの中で使われる事が多いです。
1つのフォルダ内にある複数のエクセルファイルを順番に処理する事ができるコードと動画を用意しました。
Dir関数について解説VBA|Dir関数を使ってフォルダ内の複数ファイルを順番に処理する