現在開いているブックをコピーする方法を解説します。
「開いているブックをコピー」といった場合、
やりたい処理は大きく以下の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を共有(宣言を省略)できますのでご活用ください。
このあたりの詳しい解説はこちらの記事をどうぞ。