今回は、OneDriveのフルパス対策の第二弾です。
第一弾では、OneDrive直下(OneDriveを開いてすぐの場所)にファイルを保存した場合のフルパスが取得できない時の対策方法についてお話しました。
前回の話も読んでみたい時は、「第一弾OneDrive直下のフルパス対策」も確認してみて下さいね。
今回は、保存場所に関係無くパスを修正する方法についてのお話です。
それでは、早速本編へ行ってみましょう。
OneDriveのどこに保存してもフルパスを取得する方法
まずは、完成コードから見ていきましょう。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Option Explicit Sub OneDriveのパス設定() Dim Tgt, Path As String , i, cnt As Long Tgt = ThisWorkbook.Path 'URLの部分を削除してフルパスを作ります If Left(ThisWorkbook.Path, 5) = "https" Then For i = 1 To Len(Tgt) If Mid(Tgt, i, 1) = "/" Then cnt = cnt + 1 Next i If cnt = 3 Then Path = Environ( "UserProfile" ) & "¥OneDrive" Else cnt = 0 For i = 1 To Len(Tgt) If Mid(Tgt, 1, 1) = "/" Then cnt = cnt + 1 If cnt < 4 Then Tgt = Right(Tgt, Len(Tgt) - 1) Else Exit For End If Next i Path = Replace(Environ( "UserProfile" ) & "¥OneDrive" & Tgt, "/" , "¥" ) End If Else Path = ThisWorkbook.Path End If MsgBox Path ' Debug.Print Path End Sub |
これが完成コードです。
(コード上でダブルクリックすると全て選択出来るので、必要に応じてコピペして使って下さい)
ちなみに「MsgBox Path」「’ Debug.Print Path」は、パスの結果をメッセージボックスで表示するか、イミディエイトウィンドウに結果を残すかの違いなので、自由に使って下さい。
もう少しスマートなやり方もあると思いますが、コレでご勘弁を。
今回のコードを実行したのがコレです。

デスクトップに保存した場合のフルパスを取得した結果です。

こっちがOneDriveにテスト用のフォルダをいくつか作って、フルパスを取得できるようにした結果です。
こんな風にOneDriveのどの階層でもフルパスを取得できるようになっています。
それじゃあ、改良版のフルパス取得のコードについて説明していきましょう。
基本的な条件を切り分けよう
まずは、ハイライトされたコードを解説しましょう
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Option Explicit Sub OneDriveのパス設定() Dim Tgt, Path As String , i, cnt As Long Tgt = ThisWorkbook.Path 'URLの部分を削除してフルパスを作ります If Left(ThisWorkbook.Path, 5) = "https" Then For i = 1 To Len(Tgt) If Mid(Tgt, i, 1) = "/" Then cnt = cnt + 1 Next i If cnt = 3 Then Path = Environ( "UserProfile" ) & "¥OneDrive" Else cnt = 0 For i = 1 To Len(Tgt) If Mid(Tgt, 1, 1) = "/" Then cnt = cnt + 1 If cnt < 4 Then Tgt = Right(Tgt, Len(Tgt) - 1) Else Exit For End If Next i Path = Replace(Environ( "UserProfile" ) & "¥OneDrive" & Tgt, "/" , "¥" ) End If Else Path = ThisWorkbook.Path End If MsgBox Path ' Debug.Print Path End Sub |
まず、基本的な条件を分岐させましょう。
ハイライトされたIF文の内容だけ切り取ってみます。
1 2 3 4 | If Left(ThisWorkbook.Path, 5) = "https" Then Else Path = ThisWorkbook.Path End If |
この部分の意味は、このブックのパスの「左から5文字」を取得します。
その文字が「https」だった場合は、続きの処理をしてね。
そうじゃなかったら、「Pathという変数にこのブックのフルパスを格納」してね。
という意味になります。
要は、フルパスを取得して「https」から始まった場合は修正する処理へ
そうでない場合(問題なくフルパスを取得できれば)はフルパスを「Pathという変数」に格納してね。
というコードなんです。
続いて、ハイライトのFor文の解説をしましょう。
10 11 12 | For i = 1 To Len(Tgt) If Mid(Tgt, i, 1) = "/" Then cnt = cnt + 1 Next i |
この処理の目的は、フルパスに「/」がいくつ含まれているか調べることです。
なので、フルパスの文字数を「Len関数」を使って調べています。
(Len関数は文字数を調べてくれる関数です)
仮にフルパスが100文字だったとしたら、100回同じこと繰り返します。
その繰り返し処理をしてくれる回数を決めています。
コードは、「For i = 1 To Len(Tgt)」なのでフルパスの文字数分(仮に100文字)だったら100回繰り返し処理しなさいという意味なんですね。
次の問題は、「/」をどうやって数えて保存するのか? ということです。
そこは、IF分を使ってフルパスを1文字ずつ調べて、「/」があったら、「cntという変数」に見つけるたびに数えた数を合計して格納しなさいという設定をします。
ただ、それをプログラムでやってもらおうと思ったら、調べ方を教えてあげなきゃいけなんですね。
そこで「If Mid(Tgt, i, 1) = “/” Then」で調べ方を教えてあげます。
Mid関数は、「Mid(【調べたい内容】,【調べる先頭の位置】,【何文字調べるかを指定】)」つまり
「フルパス(仮に100文字)を左から1文字ずつ100文字目になるまで一文字ずつ調べてね。」
という意味になります。
で、調べた文字が「/」だったら、cntという変数に調べた結果を格納してね。
という意味になるんですね。
見つけたら、変数にカウントした結果を残す処理が「cnt = cnt + 1」の部分です。
「/」見つけた!! → cntに1を格納 → またあった!! → cntにある1に1を足して「2」にして格納
という意味のコードです。
ここまでが、基本的な条件の切り分け作業です。
今回は、コードが長いので一旦コーヒーブレイクでもして頭の中を整理しておくと良いですね。
では、続きを解説していきましょう。
4つ目の「/」より前を削ってフルパスを作ろう
次は、今回の話で一番重要な部分です。
少し複雑ですが、少しずつバラしてみることで対応方法が分かってきますよ。
さっそくハイライト部分を確認していきましょう。
01 02 03 04 05 06 07 08 09 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 | Option Explicit Sub OneDriveのパス設定() Dim Tgt, Path As String , i, cnt As Long Tgt = ThisWorkbook.Path 'URLの部分を削除してフルパスを作ります If Left(ThisWorkbook.Path, 5) = "https" Then For i = 1 To Len(Tgt) If Mid(Tgt, i, 1) = "/" Then cnt = cnt + 1 Next i If cnt = 3 Then Path = Environ( "UserProfile" ) & "¥OneDrive" Else cnt = 0 For i = 1 To Len(Tgt) If Mid(Tgt, 1, 1) = "/" Then cnt = cnt + 1 If cnt < 4 Then Tgt = Right(Tgt, Len(Tgt) - 1) Else Exit For End If Next i Path = Replace(Environ( "UserProfile" ) & "¥OneDrive" & Tgt, "/" , "¥" ) End If Else Path = ThisWorkbook.Path End If MsgBox Path ' Debug.Print Path End Sub |
解説前に補足ですが、14~16行目は第一弾で解説しているので詳しい解説は省略しますね。
17行目の「cnt = 0」はcntという変数の値をリセットする為に「0」を格納してリセットしています。
14 15 16 | If cnt = 3 Then Path = Environ( "UserProfile" ) & "¥OneDrive" Else |
まず、「If cnt = 3 Then」の部分は、「/」の数が、3だった場合の条件式です。
「/」の数が3つというのは取得したパスが、「https://d.docs.live.net/~」という状態です。
つまりOneDriveの直下に保存されているという状態ですね。
そこで、「Environ(“UserProfile”) & “¥OneDrive”」で設定した「C:\Users\コンピューター名\OneDrive」をPath変数に格納します。これでOneDrive直下のパスの修正はOKです。
今回の話で一番重要な処理がこの部分です。
18 19 20 21 22 23 24 25 | For i = 1 To Len(Tgt) If Mid(Tgt, 1, 1) = "/" Then cnt = cnt + 1 If cnt < 4 Then Tgt = Right(Tgt, Len(Tgt) - 1) Else Exit For End If Next i |
この部分を簡単に説明すると
仮に「https://d.docs.live.net/12345/test/test/test」というフルパスを取得したとしましょう。
このパスを1文字ずつ調べていきます。
調べた結果「/」じゃなかった場合は、一番最初の1文字を減らして「/」かどうか調べます。
これを繰り返して、1文字目が4つ目の「/」だったら繰り返しの処理を終了してフルパスを作る処理に移ります。
もう少し詳しく説明すると
If Mid(Tgt, 1, 1) = “/” Then cnt = cnt + 1 で先頭の1文字ずつ調べます
1回目 → 「https://d.docs.live.net/12345/test/test/test」
調べた文字(1文字目)は「h」なので「変数cnt」には「0」が格納されます。
次の処理に移ります。
20 21 22 23 24 | If cnt < 4 Then Tgt = Right(Tgt, Len(Tgt) - 1) Else Exit For End If |
この処理は、cntが4より小さい場合、「フルパスの文字数-1文字分、右側から取得する」という処理なので「変数tgt」には「ttps://d.docs.live.net/12345/test/test/test」という値が格納されるんですね。
「https://d.docs.live.net/12345/test/test/test」の文字数は44文字だったので、44文字―1文字 → 右から43文字を「変数tgt」に入れますよということです。
つまり、頭の文字1字を削ることと同じことですよね。
コレを繰り返すと……
「/test/test/test」という文字が「変数tgt」に格納されます。
なぜなら、左から「/」を数えると4個目位置が「/test/test/test」なのでcntの値が4以上になったら、「Exit For」で繰り返し処理を抜けるからです。
「Exit For」はFor文の処理を強制的に抜け出す方法なので、コレでいい感じに必要なパスを取得できました。
OneDriveのパス問題は、「https://d.docs.live.net/12345」が邪魔なことです。
言い方を変えると、4つ目の「/」より左側全部を削れればOKということ
考え方がちょっと複雑ですが、これでファイルをどこに保存しても(階層が深くなっても)パスを修正できるようになるという訳です。
さて次で最後です。
26 | Path = Replace(Environ( "UserProfile" ) & "¥OneDrive" & Tgt, "/" , "¥" ) |
最後の仕上げは、パスの「/」を「¥」に変更することです。
「Environ(“UserProfile”) & “¥OneDrive”」の部分は、第一弾で説明した
「C:\Users\パソコン名\OneDrive」でOneDriveの直下まで設定しています。「& Tgt」でOneDrive直下のパスとtgt変数の中身である「/test/test/test」を繋げます。
つまり「C:\Users\パソコン名\OneDrive/test/test/test」というパスもどき? の出来上がりです。仕上げにReplace(パスもどき, “/”, “¥”)の部分です。
Replace関数は、パスもどきに含まれている「/」を「\」に変換してくれる関数です。 つまり、「C:\Users\パソコン名\OneDrive\test\test\test」になります。コレでフルパスが完成しました。やったね!!
まとめ
さて、今回のお話は役に立ったでしょうか。
今回のポイントは、どうやって必要のない文字を特定して、いい感じに切り取れるか。
ここが重要は部分です。
結果だけ見ると大したことはしてはしてないんですが、プログラムにすると結構長い処理ですよね
一番発想が必要な部分は、Right関数の部分なんですが、「全体の文字数-全体から一文字引いた文字数」で一文字削ったことと同じになるという発想が出ないと、この機能は実現できなかったと思います。
今回のような困ったときに役立つ対処法をこれからも増やしていきたいです。
最後まで読んでいただき、ありがとうございました。
それでは次回またお会いしましょう。
グッバ~イ!!
【OneDrive直下のフルパスを修正する方法】も見てみる フルパス修正基本編
[…] […]