【簡単エクセル/Excel VBA マクロ】OneDrive環境で FileSystemObject やDir関数を正常に動作させる方法|ワンポイントテクニック #011



いつもありがとうございます。
ノンプログラマー向け「Excel VBA マクロ ワンポイントテクニック解説シリーズ」へようこそ。
本稿では「OneDrive環境で FileSystemObject やDir関数を正常に動作させる方法」を解説いたします。
近年、クラウド環境の普及により、データをPCのローカルではなくクラウドに保存するのが一般的になってきました。
OneDriveは、Microsoftが提供するクラウドストレージサービスです。ファイルをオンラインに保存でき、PCやスマートフォンから簡単にアクセスできるため、データのバックアップや共有がスムーズに行えます。
しかし、クラウドのOneDriveに保存したファイルは、ローカルに保存している場合と異なり、ファイルパスがURL型(https://...)に変わってしまいます。
その影響で、コード内にファイルやフォルダを操作するための「FileSystemObject」や「Dir関数」を使用している場合、正常にコードが動作しなくなってしまいます。
なお、FileSystemObjectは、ファイルやフォルダを操作する際、必ずしも必要になるわけではありませんが、結果として多くのマクロで良く使われています。
なぜならば、ある程度の操作はFileSystemObjectを使わずにローレベルコードで実装することも可能ですが、FileSystemObject は多機能であり、コードを簡潔に記述できるなどの利便性もある上、FileSystemObjectでないと難しい操作もあるためです。
そこで本稿では、FileSystemObjectやDir関数を使用していても、OneDrive環境でマクロを正常に動作させる方法を解説いたします。
この方法は、VBAを本格的に扱っている上級者向けの技術と言って良いと思います。この方法を活用すれば、あなたのVBAマクロは、よりプロフェッショナルなものとなり、その価値をさらに高められるでしょう。
VBAを活用して、自分やコミュニティに合ったアプリを作成し、仕事量は半分に、成果は2倍にしていきましょう!初心者の方にも分かりやすく丁寧に解説していきますので、ぜひ最後までご覧ください。
【基本的な挙動】ローカルとクラウドのOneDriveの同期の仕組み
ローカル環境にもOneDriveのフォルダは存在します。
C:\Users\あなたのユーザー名\OneDrive
このローカルのOneDriveフォルダは、クラウド上のOneDriveと同期されます。

クラウドのOneDriveだけにファイルを保存することも可能ですが、通常はクラウドのOneDriveにファイルを保存すると自動的にローカルのOneDriveフォルダにも同じファイルが生成され、同期されます。下図のように、緑のチェックマークがついていればOneDriveとローカルとで同期されている状態です。

もし同期されていなければ、次のような「雲マーク」が表示されているはずです。

その場合は、ファイルの右クリックメニューの「このデバイス上に常に保持する」をクリックすると同期されます。

今回紹介する方法で正常にコードを動作させるためには、このようにローカル環境とクラウド環境のファイルの同期が正常に行われている必要があります。
【根本原因】ローカルとクラウドのOneDriveではファイルパスが違う
ここが根本原因です。
ローカルとクラウドのOneDrive上の「ドキュメント」フォルダのパスの違いを見てみましょう。次のようになります。
' ローカルのOneDrive
C:\Users\あなたのユーザー名\OneDrive\ドキュメント
' クラウドのOneDrive
https://d.docs.live.net/あなたのOneDriveの識別番号/ドキュメント
"あなたのOneDriveの識別番号" には、OneDriveごとに異なる英数字の一意の識別番号が割り当てられます。
このファイルパスの違いが、マクロが正常に動作しない原因となります。

・・・
【問題点】FileSystemObjectやDir関数はクラウドのOneDriveのパス(https://...)に対応していない
たとえば、クラウド上に次のVBAコードを記述したファイルを置いてコードを実行し、ファイルパスを取得してみましょう。
' フォルダ構成
your_onedrive(cloud)/
└── ドキュメント/
└── 自身のファイルパスを取得する.xlsm
Sub ShowThisWorkbookPath()
Debug.Print ThisWorkbook.Path
End Sub
このコードを実行すると次のように、https://
から始まるクラウド上のパスが返ってきます。
' コード実行結果
https://d.docs.live.net/あなたのOneDriveの識別番号/ドキュメント
このパスでも、たとえば、次のように単純にファイルを開いたりするような操作は正常に実行できます。
Sub OpenFile()
' 変数宣言
Dim wb As Workbook
' ファイルを開く
Set wb = Workbooks.Open(ThisWorkbook.Path & "\Book1.xlsx") ' 正常に開ける
End Sub
しかし、FileSystemObjectやDir関数を使うとエラーが発生します。
次の例を見てみましょう。これは、FileSystemObjectを使用してフォルダを取得するコードですが、エラーが発生ます。
Sub GetFolderWithFSO()
' 変数宣言
Dim fso As FileSystemObject ' ファイルシステムオブジェクト
Dim folder As folder ' フォルダーオブジェクト
' ファイルシステムオブジェクトをインスタンス化
Set fso = New FileSystemObject
' フォルダーをオブジェクト変数に代入
Set folder = fso.GetFolder(ThisWorkbook.Path) ' ここでエラーが発生
Debug.Print folder.Path
End Sub

このエラーが発生する原因は、FileSystemObject が、https://
から始まるクラウドのOneDriveのパスに対応していないことです。FileSystemObject やDir関数は、ローカルファイルシステム専用なんですね。

・・・
【解決方法】Environ関数を使いローカルのファイルパスを渡す
OneDrive環境で、FileSystemObjectやDir関数を使用したマクロを動作させるには、Environ関数でローカルのファイルパスを生成し、それをFileSystemObjectやDir関数に渡す必要があります。
具体例を示します。
Sub GetFolderWithFSO2()
' 変数宣言
Dim fso As FileSystemObject ' ファイルシステムオブジェクト
Dim folder As folder ' フォルダーオブジェクト
Dim local_this_wb_path As String ' ローカル基準のファイルパス
' ファイルシステムオブジェクトをインスタンス化
Set fso = New FileSystemObject
' URL型のファイルパスをローカルのファイルパスに変換
'' ThisWorkbook.Path から URL の部分を削除
local_this_wb_path = Replace( _
ThisWorkbook.Path, "https://d.docs.live.net/", "" _
)
'' パスからフォルダ名の部分を取り出す
local_this_wb_path = Mid(local_this_wb_path, InStr(local_this_wb_path, "/") + 1)
'' パスの区切り文字をWindows形式に変換
local_this_wb_path = Replace(local_this_wb_path, "/", "\")
'' ローカルのファイルパスを生成
local_this_wb_path = Environ("OneDrive") & "\" & local_this_wb_path
' フォルダーをオブジェクト変数に代入
Set folder = fso.GetFolder(local_this_wb_path)
Debug.Print "変換前のパス: " & ThisWorkbook.Path
Debug.Print "変換後のパス: " & folder.Path
End Sub
このコードでは、ThisWorkbook.Path
で得られるクラウド環境のファイルパスを、Environ
関数を使用してローカル環境のファイルパスに変換しています。そのローカル環境のファイルパスをFileSystemObjectに渡しているためエラーが発生しません。
次の結果が返ってきます。
変換前のパス: https://d.docs.live.net/あなたのOneDriveの識別番号/ドキュメント
変換後のパス: C:\Users\あなたのユーザー名\OneDrive\ドキュメント
なお、Environ
関数の構文は次の通りです。
Environ("環境変数名")

以上で、OneDrive環境でマクロを動かす方法の解説は終了です。ありがとうございました。
補足
ユーザーによっては、OneDriveと同期させずに、純粋なローカル環境でマクロを動作させるケースもあると思います。そのようなケースが想定される場合は、まずIf構文で現在の環境がOneDriveと同期している環境かローカルのみの環境かを判定し、その結果に応じて後続の処理を実行するようにコードを実装すると良いでしょう。
' 例
' ThisWorkbook.Pathの種類を判定(OneDrive対応)
If Left(ThisWorkbook.Path, 8) = "https://" Then
' ローカルのOneDriveのパスに変換する
Else
' 通常のローカルのファイルパスを使う
End If
おわりに


ご覧いただきありがとうございました。
今回の記事では、「OneDrive環境で FileSystemObject やDir関数を正常に動作させる方法」を解説いたしました。
お問い合わせやご要望等ございましたら、「お問い合わせ/ご要望」またはコメントにて、ご連絡いただければ幸いでございます。
皆様の人生がより一層素晴らしいものになるよう、少しでもお役に立てれば幸いでございます。
なお、当サイトでは様々な情報を発信しております。もしよろしければ、トップページもご覧いただけると幸いでございます。
関連記事
本稿と関連の深い記事です。もしよろしければ、合わせてご活用ください。
- 【簡単エクセル/Excel VBA マクロ】Excel VBA マクロの全体像 | みんなの実用学 (jitsuyogaku.com)
- 【簡単エクセル/Excel VBA マクロ】通常使用編目次 | みんなの実用学 (jitsuyogaku.com)
- 【簡単エクセル/Excel VBA マクロ】ワンポイントテクニック編目次 | みんなの実用学 (jitsuyogaku.com)
- 【簡単エクセル/Excel VBA マクロ】アプリ事例編目次 | みんなの実用学 (jitsuyogaku.com)
VBAプログラミングスキルアップのための参考情報
ここでは参考図書を紹介いたしますが、これらに限らず自分に合うものを選ぶことが重要だと考えております。皆様の、より一層のご成功を心よりお祈りしております。
VBAプログラミングのスキルアップ
学習用としてもハンドブックとしても役立つ便利な書籍がこちらです。価格はやや高めですが、その内容は非常に充実しています。相応のスキルを身に付けるためには、こうしたしっかりとした書籍を一冊持っておくと良いでしょう。
入門書に関しては、どの書籍も大きな違いはありません。あまり迷うことに時間をかけるよりは、手頃なものを一冊選んでみると良いでしょう。VBAの入門書は数多く出版されていますので、興味がある方はぜひチェックしてみてください。
甲乙つけがたい場合、私はインプレス社の「いちばんやさしい」シリーズを選ぶことが多いです。
\チェックしてみよう/
\チェックしてみよう/
\チェックしてみよう/
VBAのプログラミング能力を客観的に証明したい場合には「VBAエキスパート試験」があります。この試験はVBAの知識を公式に認定するものです。VBAの総合的な能力獲得を目指す方に適しています。以下の公式テキストが販売されております。
プログラミングの一般教養
「独学プログラマー」というプログラミングの魅力を解説した書籍があります。これはVBAではなくPythonを題材としていますが、プログラミングの基本的な知識や思考法、仕事の進め方まで幅広く学べます。
こちらの記事でも紹介しております。もしよろしければご覧ください。
