メインコンテンツへスキップ
見出し画像

【VBA裏技】OneDriveに保存したエクセルで、ThisWorkBook.Pathを使ってコンピュータのローカルパスを得る(ソース変更不要)

    ある日会社でいつも通り自分のための効率化をしていたところ、エラーが発生。
    パスが見つかりませんと言う、今さらすぎるエラー。
    なんだよと中身を見てみたところ、なぜかThisWorkBook.PathがURLになってる…

    画像

    どうやらOneDriveと同期しているフォルダに保存したエクセルを開くと、ThisWorkBook.PathがURL を返すようになるらしい。
    少し調べたところ、これを根本的に解決するような仕様はなかった…。

    解決策を調べると、URLをOneDriveフォルダの環境変数などで置換して本来のパスを取得するなどの方法が見つかったが、もうちょい良い方法ないかと考えた。
    そして思いついた裏技を使うことによって、見事ソースコードを一切変更することなく、このエラーを解決することができた。

    症状

    具体的な症状はこちら
    今まで普通に動いていたマクロがいきなりファイルが見つからないやパスが見つからないなどのエラーで突然動かなくなる。

    画像

    例えばこんな感じでファイルを読み取るソースを書いたとしても…

    Option Explicit
    
    Sub test()
      Open ThisWorkbook.Path & "\test.txt" For Input As #1
      Dim buf As String
      Do Until EOF(1)
        Line Input #1, buf
        Debug.Print buf
      Loop
    End Sub

    ↑で紹介したこのエラーになります

    画像

    そして、私の考えた解決策を用いると以下のようになります
    これはテキストファイルの中身をイミディエイトウィンドウに表示するコードなので、正常に動作していることが分かります。
    ※もちろんこの時もOneDriveと同期しています

    画像

    ちなみにテキストファイルの中身は以下です

    画像

    解決策

    これから紹介する方法を使用することにより、ソースコードを一切変更することなく、この問題を解決することができます。
    もちろん、外部のアプリケーションを使用するようなことはありません。Windowsの標準機能で全て解決します。

    裏技の答えは、"ジャンクション"を使う。
    ジャンクションはハードリンクのフォルダ版だと思えばいい。
    ハードリンクとは、ただのリンクと違い、そのファイルそのものを直に参照する。
    ちょっとたとえが難しいが、一人の人間が複数の戸籍を持っていて、どっちの戸籍を見ても同じ人間にたどり着くようなものと思ってもらえればいいでしょう。
    要するに…
    元々以下のようにOneDriveフォルダに保存していたものを
    C:\Users\MyUser\OneDrive\test\Test.xmsl
    以下のように別のフォルダに入った状態で起動/運用できるということ
    この時点でThisWorkbook.parhがローカルのパスを返すようになります。
    C:\Users\MyUser\data\test\Test.xmsl
    パスが違うから違うフォルダじゃないか!!と思うかもしれませんが、太字にした"test"のフォルダをジャンクションにすることで、このパスは同じファイルを参照するパスになります。
    つまり、"C:\Users\MyUser\data\test\"フォルダの中身をいじると"C:\Users\MyUser\OneDrive\test\"の中身も同時に変更されるということです。
    "C:\Users\MyUser\data\test\"のフォルダを使用して作業を行うことでパスに対する問題を解決しつつ、OneDriveへの同期も可能ということですね。
    (同時に変更するという表現は厳密には正しくなく、本来はどっちも同じものである)

    具体的なやり方

    ジャンクションはコマンドプロンプトを使用することで簡単に作成することができます。
    構文:
    MKLINK /J "ジャンクションのパス" "元のパス(OneDriveフォルダ)"
    例:
    mklink /j C:\Users\Rcat999\data\test "C:\Users\Rcat999\OneDrive\test"

    このコマンドを実行することで"C:\Users\Rcat999\OneDrive\test"に対するジャンクション"C:\Users\Rcat999\data\test"が作成されます。

    画像

    左側がOneDriveのフォルダで右側がジャンクションです。
    中身や更新日時なども完全に同一であることが分かります。
    先ほども述べたように、ジャンクションとはハードリンクのフォルダ版のようなものなので、片方でデータを消せばもう片方でも消えてしまいますのでご注意ください。

    画像

    まとめ

    以上が解決策になります。
    ジャンクションを使用すると同じフォルダを複数のパスで使用することができるようになるので、時と場合によっては非常に便利です。
    例えば、今回のようにワンドライブとローカルパスを切り分けたい場合に特に便利だと思います。
    ただし、ジャンクションの削除には注意してください。ミスると全部データが消えます。

     
     
    モノづくりが趣味。 "売ってないなら自分で作ればいいじゃない"をコンセプトに、機械/電気/AI/プログラム/ネットワーク 全部やります。 記事執筆はAI不使用。 ご連絡や利用規約はプロフィール記事参照。

    あなたへのおすすめ