はじめに
VBA マクロを使用していると、OneDrive のパスを取得しようとすると、https://xxxxx のパスを取得しまいエクスプローラーからアクセスできず、「パスが見つかりません」といったエラーが吐かれます。そこで、OneDrive のパスをローカルパスに変換してくれる VBA マクロの関数を作成しました。できるだけ汎用性を高め、共同で VBA マクロを使用することを前提としています。
実装
以下、ソースコードになります。具体的な流れは以下の通りです。
- 関数
GetPath
に引数としてurl
を渡します。これは変換するパス(ローカルパスまたは URL)です。 -
userName
変数にEnviron("USERNAME")
を利用し、システム環境変数からユーザー名を代入します。 -
oneDrivePath
変数に、OneDrive のローカルパスを代入します。このパスは "C:\Users\ユーザー名\OneDrive - xxxxxx" の形で xxxxx の部分は、各々の環境により異なってくるかと思います。 -
fso
という FileSystemObject のインスタンスを作成します。FileSystemObject は、ファイルシステムの操作(ファイルやフォルダの作成、削除、移動など)を行うためのオブジェクトになります。 - 引数として与えられた
url
が "https:" から始まる場合(URL 形式である場合)に以下の操作を行います。
- OneDrive の各サブフォルダについてループを行います。
- 各サブフォルダの名前(
subfolder.Name
)を取得し、その名前が URL 内に存在する位置(subfolderPosition
)を取得します。これにはInStr
関数が使用されています。 - サブフォルダの名前が URL 内に存在する(
subfolderPosition > 0
)場合、URL からそのサブフォルダの名前を含む部分から後ろの部分(relativePath
)を取得します。これにはMid
関数が使用されます。 - 取得した相対パス(
relativePath
)を OneDrive のルートパス(oneDrivePath
)に追加して、完全なローカルパスを作成します。そしてこのパスを戻り値として返します。
具体例を挙げて説明していきましょう。
例えば、次のような URL が引数として渡されたとします。
https://onedrive.live.com/?id=Documents/Project/FileName&cid=xxxxxx
この時、 "Documents/Project/FileName" は、OneDrive上のフォルダ構造を表します。この場合、"Documents"、"Project" はサブフォルダの名前で、"FileName" はファイルの名前です。
そして、VBA マクロは、この URL を次のようなローカルの OneDrive パスに変換します。
C:\Users\ユーザー名\OneDrive - xxxxxx\Documents\Project\FileName
具体的な処理は次の通りです。
- まず、URL が "https:" で始まるかどうかを確認します。
- "https:" で始まる場合、URL に含まれる各サブフォルダ(この例では "Documents" と "Project")がローカルのOneDrive のどのサブフォルダに対応するかを探します。これは OneDrive のルートフォルダからサブフォルダを一つずつ調べていくことで行います。
- 対応するサブフォルダが見つかった場合、そのサブフォルダ名を含む部分から URL の終わりまでの部分を取り出し、それをローカルの OneDrive パスに追加します。この結果が変換後のローカルパスになります。このようにして、URL がローカルパスに変換されます。これにより、OneDrive のウェブ上のパスとローカルのパスを相互に変換することができます。
' OneDrive内のパスの取得時にurlになる可能性があるパスをローカルパスに変換
Function GetPath(url As String) As String
Dim oneDrivePath As String
Dim userName As String
Dim shortcut As Object
Dim subfolder As Object
Dim fso As Object ' ファイルシステム操作をするためのオブジェクト
userName = Environ("USERNAME")
oneDrivePath = "C:\Users\" & userName & "\OneDrive - xxxxxx\"
Dim folder As Object
' FileSystemObjectのインスタンスを作成
Set fso = CreateObject("Scripting.FileSystemObject")
Set folder = fso.GetFolder(oneDrivePath)
'パスにhttps:が含まれる場合
If url Like "https:*" Then
For Each subfolder In folder.SubFolders
Dim subfolderName As String
subfolderName = subfolder.Name
Dim subfolderPosition As Integer
subfolderPosition = InStr(1, url, subfolderName & "/") ' subfolderNameの位置を取得
If subfolderPosition > 0 Then
Dim relativePath As String
relativePath = Mid(url, subfolderPosition) ' subfolderNameを含む部分からのパスを取得
GetPath = oneDrivePath & relativePath ' OneDriveパスにその部分を追加
Exit Function
End If
Next subfolder
Else
GetPath = url 'httpsを含まない場合はそのまま返す
End If
End Function
最後に
VBA マクロを作ろとした時に、OneDrive のパスが取得できず、困っていました。そこで色々調べていったところ、OneDrive 内のパスをローカルパスに変換する方法が見つかりました。今回はそのソースコードを改良し、OneDrive のパスがどれだけ深くても、ローカルパスに変換してくれるようにしました。ぜひ VBA マクロを利用するときには、GetPath
関数を使ってみて下さい。