和風スパゲティのレシピ

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

開いているファイルをコピーする - FSO.CopyFile

現在開いているブックをコピーする方法を解説します。

「開いているブックをコピー」といった場合、
やりたい処理は大きく以下の2つに分類できます。

  • 作業中のブックを別のフォルダにも保存したいなど、
    文字通り「今開いているブックをコピーしたい」
  • ファイルのコピーを実行しようとしたら、偶然そのファイルを開いていてエラーになってしまう問題の対策。
    つまり「開いていてもいなくてもいずれの場合もコピーを実行したい」


前者を実行したい場合はWorkbookオブジェクトのSaveCopyAsメソッドを、
後者を実行したい場合はFileSystemObjectのCopyFileメソッドを使用します。

WorkbookオブジェクトのSaveCopyAsメソッド

基本構文

現在開いているブックのコピーを作成したい場合は、
WorkbookオブジェクトのSaveCopyAsメソッドを実行します。

' 基本構文
対象ブック.SaveCopyAs 保存ファイルパス
' 実行例
' マクロ実行ブックのコピーを作成
ThisWorkbook.SaveCopyAs "C:\Users\wfsp\Desktop\テストフォルダ\Book1.xlsm"

' アクティブブックのコピーを作成
ThisWorkbook.SaveCopyAs "C:\Users\wfsp\Desktop\テストフォルダ\Book1.xlsx"
' マクロブックのバックアップを「ブック名_バックアップ日.xlsm」で作成
Sub 本ブックのバックアップを作成する()
    
    ' バックアップ作成フォルダを取得(なければ作る)
    Dim 保存フォルダパス As String
    保存フォルダパス = ThisWorkbook.Path & "\BackUp"
    
    On Error Resume Next
    MkDir 保存フォルダパス
    On Error GoTo 0
    
    ' ブック名を作成
    Dim 保存ブック名 As String
    保存ブック名 = Replace(ThisWorkbook.Name _
        , ".xlsm", Format(Date, "_yyyymmdd") & ".xlsm")
    
    ' ブックのコピーを作成
    ThisWorkbook.SaveCopyAs 保存フォルダパス & "\" & 保存ブック名
    
End Sub

上記のコードを実行することで、
開いているファイルのコピーを作成することが出来ます。

Workbookオブジェクトのメソッドですので、
前述の通りブックを開いていない場合は実行することはできません。


引数はファイルパスひとつだけで、
簡単に書ける分、処理にバリエーションはありません。


特に「このメソッドは常に上書き保存」である点にご注意ください。

ファイルがあったとしても無警告で上書き保存が実行され、
この設定を変える引数も存在しません。


上書きしたくない場合はDir関数でファイルの存在確認を行うか、
後述のFileSystemObjectのCopyFileを使用してください。

' ファイルの存在確認をしてから実行
If Dir(保存ファイルパス) = "" Then
    ThisWorkbook.SaveCopyAs 保存ファイルパス
End If
' FileSystemObjectのCopyFileメソッドを使用
FSO.CopyFile ThisWorkbook.FullName _
                  , ThisWorkbook.Path & "バックアップ\" ,OverWriteFiles:=False

 

FileSystemObject.CopyFileメソッド

基本構文

ファイルの開閉に関わらずコピーを実行したい場合は、
FileSystemObjectを用いて以下のコードを実行します。

' 基本構文
FSO.CopyFile コピー元ファイルパス, コピー先ファイルパス
' 実行例
Sub 開いているファイルをコピーする()

    Dim FSO As New FileSystemObject

    FSO.CopyFile "C:\Users\○○\Desktop\テストフォルダ\Book1.xlsx" _
                      , "C:\Users\○○\Desktop\テストフォルダ\Book1のコピー.xlsx"

End Sub

これでBook1を開いていたとしてもコピーを実行できますし、
前述の通りBook1を開いていなくても実行できます

ファイルの開閉に関わらずコピーを実行したい場合はこちらを使用してください。


なお、Book1が「編集されている がまだ保存していないブック」の場合、
編集前(保存時)のファイルがコピーされることになります。

開いているブックに未保存の編集がある場合はご注意ください。


ちなみにこの処理はファイルの種類を問いませんので、
Excelファイルでないその他のファイルに実行しても大丈夫です。


なお、FileSystemObjectを使用するためには、
「Scripting Runtime」の参照設定が必要です。

設定方法についてはこちらの記事をご覧ください。

参照設定せずにCopyFileメソッドを使用したいときは、

Dim FSO As New FileSystemObject

' ⇩ 書き換え

Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")

このように書き換えることで参照設定なしで使用できますが、
FileSystemObjectは参照設定が推奨される機能です。

慣れれば10秒かかりませんので、
よほどお急ぎでない限りは参照設定をしたうえでご利用ください。

※ 参照設定が推奨される理由も上記の記事で説明しています

細かい仕様

上記コードのようにCopyFileメソッドは「ファイル名の設定」も同時にできますが、
同名で別フォルダに保存するだけなら以下のコードでも実行可能です。

Sub 開いているファイルをコピーする()

    Dim FSO As New FileSystemObject

    FSO.CopyFile "C:\Users\○○\Desktop\テスト1フォルダ\Book1.xlsx" _
                      , "C:\Users\○○\Desktop\テスト2フォルダ\"

End Sub

この書き方も便利ですので覚えておきましょう。


また、コピー先に同名ファイルがあった場合は、
CopyFileメソッドはデフォルトでは「上書き保存」される仕様です。

既存ファイルがある場合はエラーになってほしいときは、
以下のように第3引数「OverWriteFiles」をFalseにしてください。
※ 省略時はTrueとなっています。

' 同名ファイルを上書きしない(エラーが出るようになる)
FSO.CopyFile 元ファイルパス, 行先ファイルパス, OverWriteFiles:= False

 

FileCopyステートメントでは不可

ファイルのコピーには有名な「FileCopyステートメント」がありますが、
こちらでは開いているファイルに実行するとエラーになります。

これに困って本記事にたどり着いた方もいるかもしれません。


残念ながらこのエラーを解消する方法はありませんので、
諦めてFileSystemObject.CopyFileメソッドを使用してください。


ついでですが、細かい仕様に書いた

  • フォルダ移動ならブック名省略可
  • 既存ファイルがあれば上書きせずにエラーを出す

これらの機能もFileCopyステートメントにはない機能ですので、
この機会にすべてのコピーをFSO.CopyFileメソッドにしてしまってもよいです。


その場合は、以下のように「FSO」の宣言をSubの外(一番上)に出すことで、

Public FSO As New FileSystemObject

Sub 開いているファイルをコピーする()

    FSO.CopyFile "C:\Users\○○\Desktop\テスト1フォルダ\Book1.xlsx" _
               , "C:\Users\○○\Desktop\テスト2フォルダ\"

End Sub

これですべてのプロシージャでFSOを共有(宣言を省略)できますのでご活用ください。

このあたりの詳しい解説はこちらの記事をどうぞ。