和風スパゲティのレシピ

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

フォルダをコピーする - FSO.CopyFolder

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


フォルダごとコピーする方法がDir関数群にはないため、
必然的にFileSystemObject(以下FSO)を使うことになる処理です。

FSOについてはこちらを参照ください。
www.limecode.jp

基本形

FSO.CopyFolder コピー元フォルダパス, コピー先フォルダパス, 上書きするか(True/False)

実行例

Dim FSO As New FileSystemObject

' 同フォルダ内にコピー
FSO.CopyFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ1\対象フォルダのコピー"

' 同名で別フォルダにコピー
FSO.CopyFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                      , "C:\Users\○○\Desktop\親フォルダ2\"

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

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

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

解説

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


コピー先のパスには末尾に\ありと\なしの2通りの記載ができ、

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

という動きになります。


\があるなしでまったく違う動きになりますので注意しましょう。
特に「\のつけ忘れ」に注意してください。

' 同名で別フォルダにコピー
FSO.CopyFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                    , "C:\Users\○○\Desktop\親フォルダ2\"

' Desktop内に親フォルダ2という名前に変更してコピー
FSO.CopyFolder "C:\Users\○○\Desktop\親フォルダ1\対象フォルダ" _
                    , "C:\Users\○○\Desktop\親フォルダ2"
' ↑親フォルダ2が既に存在していれば各ファイルが上書きされる

 

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

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


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


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

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

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

第3引数(OverWrite)の上書き設定について

第3引数のOverWriteは上書きするかどうかを設定しますが、
Trueの際に実際に上書きされるのはフォルダではなくファイルです。

つまり、

  • [ファイルA][ファイルB]が入っているフォルダXを
  • [ファイルB][ファイルC]が入っているフォルダYにコピー

した場合、重複しているファイルBが上書きされ、

  • ファイルABCが3つ入ったフォルダY

が出来上がります。


フォルダごと上書きするのではなく、各ファイルをそれぞれ比較しますので、
元からフォルダYにあったファイルが消えることはありません。


要するに、

フォルダの統合ウィンドウ

これで上書きを選んだ時と同じということですね。


ただし、上記のウィンドウで「スキップ」を選んだ処理はできません。

CopyFolderの第3引数にFalseを渡した場合は、
スキップするのではなくエラーが起きるようになります。
※ On Error Resume Nextを使用してもスキップにはなりません。


既存のファイルは上書きせずにコピーを行いたい場合は、
専用のコードを書く必要があります。


詳しくはこちらの記事をご覧ください。
www.limecode.jp

発生するエラー

コピーするフォルダを開いている

コピーするフォルダ内のいずれかのファイルを開いていると、

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

エラーとなります。

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

コピー先の親フォルダが存在しない場合は、

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

エラーとなります。


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

コピー先に既にフォルダがある(OverWrite:=False時)

こちらは前述のとおりです。

どちらかと言えばわざと出すためのエラーですね。


「多分フォルダ名が被ることはない」という処理を行うとき、
万が一フォルダ名が被ってもエラーで止まってくれる機能です。


エラーは出るより出ない方が怖いですからね。

名前が被った場合の処理を書くのが面倒だな~と思ったら、
「とりあえずFalseだけ渡しておけば最悪ファイルが消えることはない」
という使い方ができますのでご活用ください。