和風スパゲティのレシピ

日本語でコーディングするExcelVBA

フォルダを移動する - FSO.MoveFolder

中のフォルダ・サブフォルダごとフォルダを移動する、
FileSystemObject.MoveFolderメソッドの使い方を解説します。

基本形

FSO.MoveFolder 移動するフォルダパス, 移動先フォルダパス

実行例

Dim FSO As New FileSystemObject

' 同名で別フォルダに移動
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ2\"

' 移動と同時にリネーム
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ2\新フォルダ名"

' 「売上データ○○」フォルダをすべて移動
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\売上データ*" _
                      , "C:\Users\○○\Desktop\親フォルダ2\"

※ 変数FSOの宣言部についてはこちらをご覧ください。
FileSystemObjectの参照設定と変数宣言について

解説

FileSystemObjectのMoveFolderメソッドは、
移動元・行先の2つのパスを受け取ってフォルダを移動します。


移動先のパスには\ありと\なしの2通りの記載ができ、

  • \がある場合は「そのフォルダの中に同名で移動」
  • \がない場合は「そのフォルダパスに移動&名称変更」

という動きになります。


\があるなしでまったく違う動きになりますので注意しましょう。
特に「\のつけ忘れ」が頻出エラーです。

' 同名で別フォルダに移動
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ2\"

' Desktopに移動して親フォルダ2という名前に変更
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ2"
' ↑親フォルダ2が既に存在していればエラー

 

また、MoveFolderメソッドは以下のワイルドカードを使用でき、
該当するすべてのフォルダを一括移動することができます。

* 任意の文字列(0文字も含む)
? 任意の1文字


非常に便利な機能ですので覚えておきましょう。


なおワイルドカード使用時は、行先パスはすべて移動先の親フォルダ扱いになり、
前述の\あるなしの違いがなくなります。

FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\*" _
                      , "C:\Users\○○\Desktop\親フォルダ2\"
' ↕ ワイルドカード「*」使用時は同じ処理になる
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\*" _
                      , "C:\Users\○○\Desktop\親フォルダ2"

ただ、下の書き方をしたコードは流用がしにくい(*を消せない)ため、
なるべく上の書き方で書くことをおすすめします。

既存のフォルダを上書きして移動したい場合

似たメソッドの「CopyFolder」には第3引数「OverWriteFiles」があるのですが、
MoveFolderメソッドには「既存フォルダを上書きして移動する」機能はありません。


またフォルダを移動する場合は、中身のファイル同士を比較し、
ファイルごとに上書き/スキップを判定したいこともあります。


それらのコードはこちらで解説していますので、
この処理を行いたい方はこちらをご覧ください。

www.limecode.jp

名前を変更する場合

MoveFolderメソッドは名前の変更にも利用できます。

' フォルダ名を変更
FSO.MoveFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ1\新フォルダ名"

このように「親フォルダまでのパスが同じパスを2つ渡す」ことで、
名前のみを変更することが可能です。


しかしMoveと言っているのに移動しないのはいらぬ誤解を招く恐れがあります。


名前を変更する場合は、素直に「FolderオブジェクトのNameプロパティ」を使い、

Dim フォルダ As Folder
Set フォルダ = FSO.GetFolder("C:\Users\○○\Desktop\親フォルダ1\対象フォルダ")

フォルダ.Name = "新フォルダ名"

このように書いた方が意図も伝わりやすく、
オブジェクトを扱うFSOらしいコードになるのでおすすめです。

発生するエラー

移動するフォルダを開いている

移動するフォルダ内のいずれかのファイルを開いていると、

実行時エラー70「書き込みできません。」

エラーとなります。

行先のひとつ上のフォルダがない

移動先の親フォルダが存在しない場合は、

実行時エラー76「パスが見つかりません。」

エラーとなります。


MoveFolderによって最終要素以外のフォルダを作ることはできません。

移動先に既にフォルダがある

前述の通りMoveFolderメソッドは上書き移動ができませんので、
移動先にフォルダがあった場合は

実行時エラー58「すでに同名のファイルが存在しています。」

エラーとなります。


移動先のフォルダが既に存在するかどうかは、
FolderExistsメソッドなどで判定を行ってください。

If FSO.FolderExists("C:\Users\○○\Desktop\テスト2") = False Then
    FSO.MoveFolder "C:\Users\○○\Desktop\テスト1" _
                            "C:\Users\○○\Desktop\テスト2"
Else
    行先のパスにすでにフォルダがあった場合の処理
End If

 
なお、複数フォルダを一括移動するワイルドカード使用時は、
同名のフォルダが見つかったところでエラーとなりますので、
それまでのフォルダは移動し終わった後で止まります。


一括とは言いますが、内部では1フォルダずつ処理されているということですね。

別のドライブに移動は不可

CドライブからDドライブへ移動しようとしたり、
ローカルフォルダからファイル共有サーバーへ移動をすると、

実行時エラー70「書き込みできません。」

エラーとなります。


これを一発で実現する方法はありませんので、

  1. まずはフォルダごとコピー
  2. そのあと元のフォルダを削除

という手順で実行する必要があります。


この処理にはFileSystemObjectが必要になりますので、
詳しくはこちらの記事をご覧ください。
www.limecode.jp