Excel VBAでマクロを作成しているとき、「実行時エラー52:ファイル名または番号が不正です」や「実行時エラー1004」が表示されて処理が止まってしまった経験はないでしょうか。
特に、最近のOffice環境で非常に多く報告されているのが、「OneDriveに保存したExcelファイルでマクロを実行すると、ThisWorkbook.Pathで取得したパスがURL(https://d.docs.live.net/〜)になってしまい、ファイル操作系処理がすべてエラーになる」というトラブルです。
以前のローカルPC環境であれば「C:\Users\名前\Documents\…」という正しいローカルパスが取得できていたにも関わらず、クラウド連携が強化された現代のExcelでは、特定の条件下でこのパスがクラウド上のURLとして返される仕様に変更されています。
本記事では、この「OneDrive環境でVBAのパスがURL化する原因」を詳しく解説するとともに、URL形式のパスを元の「ローカルPCの絶対パス」に自動変換する汎用的なVBAコード(コピペで利用可能)を徹底解説します。個人用OneDriveだけでなく、企業で利用されるSharePointやOneDrive for Business環境にも対応した情報をお届けします。
目次
- なぜOneDrive上のExcelでVBAを実行するとエラーになるのか?
- 個人用と法人用で違う!取得されるURLパターンの種類
- 解決策の鍵:「環境変数」を使ってローカルパスを特定する
- 【コピペで動く】URLをローカルパスに変換する自作関数(Function)
- 変換関数の使い方と実装例
- 高度なSharePoint環境での注意点(レジストリ参照について)
- まとめ
- よくある質問(FAQ)
1. なぜOneDrive上のExcelでVBAを実行するとエラーになるのか?
まず、なぜこのようなエラーが起こるのか、その根本的な原因を理解しておくことが重要です。原因は大きく分けて以下の2つの仕様が衝突していることにあります。
原因1:ThisWorkbook.Path が URL を返す仕様になった
最近のMicrosoft 365(旧Office 365)では、ファイルの保存先としてOneDriveがデフォルトで推奨されており、「自動保存」機能が有効になっています。この状態のExcelファイルをVBAから操作する際、自身の保存場所を取得するコマンドである ThisWorkbook.Path や ActiveWorkbook.Path を実行すると、VBAはローカルドライブのパスではなく、同期元のクラウド上のURLを返す仕様になっています。
原因2:VBAの標準機能はURL形式のパスを解釈できない
VBAにはファイルを操作するための様々な関数やステートメントが用意されています。例えば、フォルダ内のファイルを一覧で取得する Dir関数、ファイルを開く Openステートメント、または高度なファイル操作を行う FileSystemObject (FSO) などです。
しかし、これらVBAの歴史あるファイル操作系の機能は、Windowsのローカルファイルシステム(CドライブやDドライブなどのパス)を前提に設計されています。そのため、引数として「https://〜」から始まるURLを渡されると、「そのようなドライブやフォルダは存在しない」と判断してしまい、結果として実行時エラー52(ファイル名または番号が不正です)や実行時エラー76(パスが見つかりません)を引き起こすのです。
2. 個人用と法人用で違う!取得されるURLパターンの種類
パスがURL化してしまう問題に対処するためには、まずVBAがどのようなURLを返してきているかを把握する必要があります。実は、利用しているOneDriveが「個人向け」か「法人向け」かによって、返ってくるURLの文字列構造が全く異なります。
個人向けOneDriveの場合
個人のMicrosoftアカウントで利用しているOneDriveの場合、パスは以下のような形式になります。
https://d.docs.live.net/【16桁の英数字のユーザーID】/Documents/フォルダ名/ファイル名.xlsx
ローカルPC上では C:\Users\ユーザー名\OneDrive\フォルダ名\ファイル名.xlsx と保存されているものが、上記のような「d.docs.live.net」から始まるURLに置き換わります。
法人向けOneDrive(OneDrive for Business / SharePoint)の場合
企業のMicrosoft 365アカウントで利用している場合、テナント(組織)の名前が入った以下のような形式のURLになります。
https://【会社名】-my.sharepoint.com/personal/【ユーザーのメールアドレス】/Documents/フォルダ名/ファイル名.xlsx
または、SharePointの共有サイトと同期している場合は以下のようになります。
https://【会社名】.sharepoint.com/sites/【サイト名】/Shared Documents/フォルダ名/ファイル名.xlsx
これらの法人用環境では、ローカルPC上のパスは C:\Users\ユーザー名\OneDrive - 会社名\フォルダ名\ファイル名.xlsx といった形式になっています。
3. 解決策の鍵:「環境変数」を使ってローカルパスを特定する
この問題をVBAのコード内で解決するための標準的なアプローチは、「URL形式の文字列を、ローカルPCの正しい文字列に置換(変換)する関数を作る」ことです。
URLの「https://〜」から始まるクラウド上の絶対ルート部分を取り除き、代わりに「C:\Users\ユーザー名\OneDrive」というローカルの絶対ルート部分をくっつければよい、というロジックです。
ここで問題になるのが、「C:\Users\ユーザー名\OneDrive」というパスは、パソコン(ログインしているWindowsユーザー)によって異なるという点です。これを解決するために、Windowsの「環境変数」を利用します。VBAでは Environ 関数を使うことで、現在ログインしているユーザーの環境変数を取得できます。
Environ("OneDriveConsumer"): 個人用OneDriveのローカルルートパスを取得します。Environ("OneDriveCommercial"): 法人用OneDriveのローカルルートパスを取得します。Environ("OneDrive"): 最も基本となるOneDriveのローカルルートパスを取得します。
これらの環境変数から取得したローカルパスと、URLからファイル・フォルダ部分だけを抽出した文字列を合体させることで、エラーを起こさないローカルパスを生成することが可能になります。
4. 【コピペで動く】URLをローカルパスに変換する自作関数(Function)
それでは、実務で今すぐ使えるVBAのソースコードを紹介します。このコードは、標準モジュールに貼り付けて利用するユーザー定義関数(Function)です。個人用OneDriveと法人用OneDriveの両方に対応しており、渡されたパスがURLでない(すでにローカルパスである)場合は何もせずそのまま返すという安全設計になっています。
以下のコードをコピーして、VBE(Alt + F11)の標準モジュールに貼り付けてください。
Option Explicit
' =========================================================
' 関数名:ConvertOneDriveUrlToLocalPath
' 概要 :OneDriveのURL形式(https://...)パスをローカルPCのパスに変換する
' 引数 :TargetPath (String) 変換対象のパス
' 戻り値:変換後のローカルパス (String)
' =========================================================
Public Function ConvertOneDriveUrlToLocalPath(ByVal TargetPath As String) As String
' パスが "http" から始まっていない場合(すでにローカルパスの場合)はそのまま返す
If Left(LCase(TargetPath), 4) <> "http" Then
ConvertOneDriveUrlToLocalPath = TargetPath
Exit Function
End If
Dim LocalBasePath As String
Dim RelativePath As String
Dim SplitPath() As String
Dim i As Integer
' URL内に含まれる「%20」などのエンコードされた半角スペースを元に戻す
TargetPath = Replace(TargetPath, "%20", " ")
' 【パターン1】法人向けOneDrive / SharePoint の場合
If InStr(1, TargetPath, "sharepoint.com", vbTextCompare) > 0 Then
' 環境変数から法人用OneDriveのローカルパスを取得
LocalBasePath = Environ("OneDriveCommercial")
' "Documents/" 以降の文字列を相対パスとして抽出する
If InStr(1, TargetPath, "/Documents/", vbTextCompare) > 0 Then
RelativePath = Mid(TargetPath, InStr(1, TargetPath, "/Documents/", vbTextCompare) + 11)
ElseIf InStr(1, TargetPath, "/Shared Documents/", vbTextCompare) > 0 Then
RelativePath = Mid(TargetPath, InStr(1, TargetPath, "/Shared Documents/", vbTextCompare) + 18)
Else
' 該当しない場合は安全のためそのまま返す
ConvertOneDriveUrlToLocalPath = TargetPath
Exit Function
End If
' 【パターン2】個人向けOneDrive の場合 (d.docs.live.net)
ElseIf InStr(1, TargetPath, "d.docs.live.net", vbTextCompare) > 0 Then
' 環境変数から個人用OneDriveのローカルパスを取得
LocalBasePath = Environ("OneDriveConsumer")
' 取得できない場合は共通のOneDrive環境変数を試す
If LocalBasePath = "" Then LocalBasePath = Environ("OneDrive")
' URLをスラッシュ("/")で分割する
' https://d.docs.live.net/[ID]/ の部分を除外するため、インデックス4以降を取得
SplitPath = Split(TargetPath, "/")
If UBound(SplitPath) < 4 Then
ConvertOneDriveUrlToLocalPath = TargetPath
Exit Function
End If
RelativePath = ""
For i = 4 To UBound(SplitPath)
RelativePath = RelativePath & SplitPath(i) & "\"
Next i
' 末尾の余分な "\" を削除
If Right(RelativePath, 1) = "\" Then
RelativePath = Left(RelativePath, Len(RelativePath) - 1)
End If
Else
' その他のWeb URLの場合は変換せずそのまま返す
ConvertOneDriveUrlToLocalPath = TargetPath
Exit Function
End If
' クラウドパスのスラッシュ("/")をWindowsパスのバックスラッシュ("\")に置換して結合
RelativePath = Replace(RelativePath, "/", "\")
ConvertOneDriveUrlToLocalPath = LocalBasePath & "\" & RelativePath
End Function
5. 変換関数の使い方と実装例
先ほど作成した ConvertOneDriveUrlToLocalPath 関数を、普段のマクロの中でどのように呼び出して使うのか、具体的な実装例を解説します。
例1:ThisWorkbook.Path をローカルパスとして取得する
自分のファイルと同じフォルダにある別のファイルを操作したい場合などに使います。
Sub ShowLocalPath()
Dim myPath As String
' 通常の取得(URLになる可能性がある)
' myPath = ThisWorkbook.Path
' 【対策後】関数を通すことで確実にローカルパスを取得する
myPath = ConvertOneDriveUrlToLocalPath(ThisWorkbook.Path)
MsgBox "現在のローカルパスは:" & vbCrLf & myPath
End Sub
例2:FileSystemObject (FSO) と組み合わせてフォルダ内のファイルを一覧取得する
URLのままFSOに渡すとエラーになる処理も、この関数を挟むことで正常に動作します。
Sub GetFileList()
Dim fso As Object
Dim targetFolder As Object
Dim fileObj As Object
Dim localFolderPath As String
' フォルダパスをローカルパスに変換
localFolderPath = ConvertOneDriveUrlToLocalPath(ThisWorkbook.Path)
Set fso = CreateObject("Scripting.FileSystemObject")
' ローカルパスに変換されているためエラー52は発生しない
Set targetFolder = fso.GetFolder(localFolderPath)
For Each fileObj In targetFolder.Files
Debug.Print fileObj.Name
Next fileObj
Set fso = Nothing
End Sub
このように、外部ファイルやフォルダを指定する変数をセットするタイミングで、常にこの自作関数で「ラップ(包む)」してあげる癖をつけることで、OneDrive環境における予期せぬ実行時エラーを完全に予防することができます。
6. 高度なSharePoint環境での注意点(レジストリ参照について)
本記事で紹介した環境変数と文字列置換を利用したアプローチは、個人用OneDriveおよび標準的なOneDrive for Business環境において非常に有効かつ実用的です。しかし、大規模な組織での複雑なSharePoint環境においては、これだけでは対応しきれないケースが存在します。
SharePointの特定のチームサイトのドキュメントライブラリを、「OneDriveへのショートカットの追加」と「同期」という異なる方法でローカルにマウントしている場合、ローカルのフォルダ名にテナント名やサイト名が不規則に付与されるため、単純な文字列の置換規則から外れてしまうことがあります。
そのような極めて特殊な環境下で完全なローカルパス解決を行いたい場合は、Windowsのレジストリ情報(HKEY_CURRENT_USER\Software\SyncEngines\Providers\OneDrive など)からOneDriveのマウント情報を直接読み取る高度なVBAコードが必要になります。ただし、この手法はコードが非常に長大になり、レジストリの読み取り権限の問題も絡むため、まずは本記事の「環境変数による置換手法」を試し、どうしても解決しない場合のみレジストリアプローチを検討することをお勧めします。
7. まとめ
OneDrive上のExcelファイルでマクロを実行した際に起こる「パスのURL化によるエラー」について解説しました。要点は以下の通りです。
- 原因:クラウド同期されているファイルで
ThisWorkbook.Pathを取得すると「https://」で始まるURLが返されるため。 - 障害:VBAの
Dir関数やFileSystemObjectなどはローカルパス専用のため、URLを渡されると実行時エラー(エラー52等)で停止する。 - 解決策:URL形式のパスを、環境変数(
Environ("OneDrive")など)を利用して強制的にローカルPCの絶対パスに変換する自作関数を経由させる。
リモートワークの普及とMicrosoft 365の導入拡大により、今や「ExcelファイルはOneDriveに保存されている」ことが前提の時代となりました。かつてローカルで動いていたマクロが突然動かなくなった際は、まずこの「パスのURL化問題」を疑い、本記事の変換関数を実装して改修を行ってください。
8. よくある質問(FAQ)
Q1. エラーが出ずにマクロは動くのですが、Dir関数が空文字(“”)を返してきます。これも同じ原因ですか?
はい、同じ原因である可能性が高いです。Dir関数は指定されたパスが見つからない場合、エラーを出さずに空文字を返すことがあります。URL形式のパスを渡しているために「そんなファイルはない」と判定されているため、ローカルパスへ変換する関数を使用してください。
Q2. そもそもThisWorkbook.PathがURLにならないようにする設定はありませんか?
Excelのオプションから「Officeアプリケーションを使用して開いているOfficeファイルを同期する」のチェックを外す、またはOneDriveの同期を停止・一時停止することで、ローカルパスが返るようになります。しかし、これらはユーザーごとのPC設定に依存するため、不特定多数が利用するツール(社内システム等)においては、VBAのコード側でローカルパスに変換する対応をとるのが最も確実で安全なアプローチです。
Q3. Mac環境でもこのコードは動作しますか?
本記事のコードはWindows環境(Windowsの環境変数とディレクトリ構造)を前提としています。Mac用のExcelではパスの区切り文字(\ではなく:や/)や環境変数の概念が異なるため、このままでは動作しません。Mac環境のOneDriveでは、Mac専用のAppleScriptを利用したパス取得ロジックを分岐して記述する必要があります。
Q4. URLに含まれる「%20」とは何ですか?
ファイル名やフォルダ名に「半角スペース」が含まれている場合、URL上ではURLエンコードという規則により「%20」という文字列に変換されます。そのため、パスをローカルに戻す際には、Replace関数を利用して「%20」を本来の「半角スペース」に戻してあげる処理が必要不可欠です(本記事のサンプルコードにはこの処理が含まれています)。