2022年1月28日金曜日

VBAでOneDriveのパスを取得する

 世の中リモートワークの機会が増え、クラウドストレージを使う企業も増えてきたことと思います。自分の会社は準エッセンシャルワーカーな職種なためリモートワークとかないんですが、それでも会議はじめオンラインの利用機会が増えたこともあり、OneDriveを使ってね!と言われるようになりました。特に別店舗で同じカテゴリのファイルを上長が見るよ、みたいなケースで。そんな中でマクロ集計とかもするわけですが、継続的に出したいデータ作成なんかでGetOpenFileNameを使いたいときに、ルートディレクトリがOneDriveだとパスを出すのが面倒です。

具体的には”Thisworkbook.Path”とかやってもhttp://から始まるURLが戻ってくるので、操作できねーじゃん、という感じです。ただエクスプローラーからはCドライブに接続されているように見える(だって自動でバックアップされてるわけだし)ので、何かしら方法があるはずです。

「OneDrive」環境変数

ということで多少ググると、マイクロソフトのサポートページに解説がありました(今はリンク見失ってしまって貼れてないんですが)。以下の環境変数があるようです。

  1. OneDriveCommercial:企業アカウントでログインしている場合。
  2. OneDriveConsumer:個人アカウントでログインしている場合。
  3. OneDrive:原則1と同じ。なんで二つあるの?
なので、VBAからはEnviron()を使えば取得できます。例えばChDir()カレントディレクトリを変える場合のコーディングは、

ChDir(Environ(“OneDrive”))

等と書けば良い訳です。はい解決。

と言いたいところですが、実際にはもう少し問題があります。OneDrive直下ファイルだけで済めば世話がないですが、大抵はそんな訳なく、必要なファイルはサブフォルダに分かれて配置されていますよね。先に”Thisworkbook.Path”というネタを出していますが、それを取得できる方法が欲しい。

しかも現実的に、自分の職場は店舗で使っているMicrosoftアカウントが別だという。どうやって接続したのかはよくわかんないけど…。そんな事情もあり、色々考えた末に以下の方法を考えました。

文字列置換Functionを考えてみた

本当はReplace関数あたり使えると便利なんだけど、Thisworkbookから取得できるURLからInStrでディレクトリ名を探してString操作で置換することにしました。

Function OneDrivePath ( tgFile As Workbook, tgFolderName As String ) As String
 Dim fPath As String, uDir As String
  fPath = tgFile.Path
  uDir = Environ ( “OneDrive” )
 OneDrivePath = uDir & Right ( fPath, Len ( tgFile ) - InStr ( 1, fPath, _
 	tgFolderName, vbTextCompare ) - Len ( tgFolderName ) + 1 )
End Function

こんなFunctionをこしらえて、Subプロシージャから

 Dim myPath As String
 myPath = OnedrivePath ( ThisWorkbook.Path, “Documents” )

とかで呼び出すことでパスを作成できます。ちなみにFunctionのRightで文字数指定する際に+1してるのは”/“の分です。

実際に使う

これでパスを作成できたら、あとはChDirして、Application.GetOpenFileNameを呼び出せば狙ったディレクトリからファイルを選択させることができます。一般の方は割とディレクトリの概念自体を理解していないことも多いので、こういう配慮は必要です。もちろんディレクトリ固定なら直接読みに行ってもいいと思います。Open #してLine Inputして…とか。

今後はOneDriveで共有する機会もさらに増えると思われるので、覚えておくと良いかもしれません。