VBA

【VBA実践編1-6】FileSystemObjectでファイルを別のフォルダに移動する

実践編1-5で連続してファイルを編集・保存する処理を行いました。

編集したファイルは使用しないので、同じフォルダにあると次回処理をするときにもう一度処理することになるので困りますよね。

そこで、今回は処理が終わったファイルを別のフォルダに移動させるという処理をします。

VBAにはファイルを移動させる方法がいくつかありますが、今回は「FileSystemObject」のMoveFileメソッドを使った処理を紹介します。

目次

ファイルを別のフォルダに移動させるVBAコード

今回のVBAコードはこちら。

'******************************
'ファイルを別のフォルダに移動する
'引数
'currentPath:現在のファイルパス,
'destinationPath:移動先のファイルパス,
'overWrite:移動先に同名ファイルがいた場合に上書きするか(デフォルトは上書きする)
'戻り値
'移動したらTrue、失敗したらFalse
'******************************
Function Move_File(ByVal currentPath As String, _
                   ByVal destinationPath As String, _
                   Optional overWrite As Boolean = True) As Boolean
    Move_File = True
    
    '今のパスと移動先のパスが同じ場合は処理を終了する
    If currentPath = destinationPath Then
        Debug.Print "移動先と現在のフォルダが同じです"
        Move_File = False
        Exit Function
    End If

    'FileSystemObjectのオブジェクトを作成
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    '現在のフォルダに移動したいファイルがあるか
    If fso.FileExists(currentPath) = False Then
        Debug.Print "移動するファイルがみつかりません"
        Move_File = False
        Exit Function
    End If
    
    '移動先のフォルダに移動するファイルと同じ名前が存在するなら、削除する
    If fso.FileExists(destinationPath) Then
        If overWrite Then
            fso.DeleteFile destinationPath
        Else
            Debug.Print "移動先に同じファイルが存在します"
            Move_File = False
            Exit Function
        End If
    End If
    
    'ファイルを移動する
    fso.MoveFile currentPath, destinationPath
    
    Set fso = Nothing
End Function

 

今回はFunctionプロシージャにして戻り値を返すようにしています。

戻り値にファイルを移動できたかどうかを判定することで、その結果によってセルに移動が成功したかどうかの結果を入力する、といった処理ができます。

これを前回の実践編で紹介したプロシージャに組み込み、処理が終わったファイルを移動させていきます。

VBAコードの解説

今回の処理のポイントは、2つあります。

1つは「FileSystemObject」です。

「FileSystemObject」はファイルやフォルダの操作を行えるメソッドやプロパティがあり、ファイルの移動も「MoveFile」メソッドで行えます。

もう1つは、「Optional」という引数を用意しました。

「Optional」は必須ではない引数ということで、引数で指定しない場合は、デフォルトで設定している値が使用されます。

引数と戻り値の設定

'******************************
'ファイルを別のフォルダに移動する
'引数
'currentPath:現在のファイルパス,
'destinationPath:移動先のファイルパス,
'overWrite:移動先に同名ファイルがいた場合に上書きするか(デフォルトは上書きする)
'戻り値
'移動したらTrue、失敗したらFalse
'******************************
Function Move_File(ByVal currentPath As String, _
                   ByVal destinationPath As String, _
                   Optional overWrite As Boolean = True) As Boolean

 

今回のFunctionプロシージャには3つの引数があります。

currentPath: 移動するファイル名
destinationPath: 移動先のファイルパス
overWrite : 移動先に同名のファイルがあったら上書きするかどうか

「currentPath」「destinationPath」は必須ですが、「overWrite 」は必須ではありません。

引数を指定するときに、必須にしない場合は「Optional」と引数の前に記述し、「overWrite As Boolean = True」というように初期値に「True」が入るようにします。

こうすることで、引数で何も渡さなかった場合は「True」が設定されるようになります。

エラー処理1:フォルダパスの確認

Move_File = True

'今のパスと移動先のパスが同じ場合は処理を終了する
If currentPath = destinationPath Then
    Debug.Print "移動先と現在のフォルダが同じです"
    Move_File = False
    Exit Function
End If

 

「Move_File = True」は戻り値の値を設定しています。

今回の戻り値は「Boolean」型なので、TrueかFalseが戻りますが、問題なく移動できたら「True」が返るように最初に設定しておき、途中で問題が発生したら「False」に書き換えて、途中でプロシージャを終了するようにしています。

If文はエラー対策で、2つの引数が同じファイルパスだった場合、処理を終了します。

ファイル移動メソッドのためのオブジェクトを作成

'FileSystemObjectのオブジェクトを作成
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

 

ファイル移動を行うために使う「FileSystemObject」を宣言します。

宣言方法は2種類あり、今回は参照設定を行い方法の宣言で書いています。

詳しくは後述します。

エラー処理2:移動するファイルが存在するか

'現在のフォルダに移動したいファイルがあるか
If fso.FileExists(currentPath) = False Then
    Debug.Print "移動するファイルがみつかりません"
    Move_File = False
    Exit Function
End If

そもそもですが、移動するファイルが指定したフォルダパスにあるかどうかをチェックします。

ローカルでフォルダを移動するだけなら問題ありませんが、共有フォルダの場合、誤って他の人が移動してしまうとエラーが起きてしまいます。

それを回避するためにFileSystemObjectのメソッドFileExistsを使ってファイルがあるかを確認しています。

エラー処理3:移動するファイルが存在するか

'移動先のフォルダに移動するファイルと同じ名前が存在するなら、削除する
If fso.FileExists(destinationPath) Then
    If overWrite Then
        fso.DeleteFile destinationPath
    Else
        Debug.Print "移動先に同じファイルが存在します"
        Move_File = False
        Exit Function
    End If
End If

次は移動先に今から移動するファイル名と同じファイルが存在するかをチェックします。

ファイル移動のメソッドMoveFile は、同じファイルが存在した場合、エラーが発生します。

それを避けるために先に同じファイル名があるかを調べ、あった場合に上書きするかどうかを決めます。

上書きするかどうか、3つ目の引数OverWriteで決まります。

指定がない場合はTrueになり上書きになります。

上書きというのは、一度ファイルを削除してから移動するということです。

もし上書きしない場合(つまり引数でFalseを渡した場合)は、処理を終了します。

ファイル移動メソッドMoveFile でファイルを移動する

'ファイルを移動する
fso.MoveFile currentPath, destinationPath
    
Set fso = Nothing
End Function

すべてのエラー処理が終了したら、ファイルを移動します。

移動自体はたった1行で終わるので、エラー対策で必要のないものを除けばもっと単純になります。

最後にオブジェクトの参照を破棄するSet fso = Nothingを記述していますが、これはお決まりだと思って書いてください。

FileSystemObjectの参照設定をするかしないか

今回使用したFileSystemObjectは、参照設定をするかしないかでコードの書き方が違います。

参照設定とは、今回のFileSystemObjectや、Outlook、Wordなど外部のシステムを操作するための拡張機能を設定することです。

参照設定はVBE画面のツールタブにある「参照設定」から行うことができます。

参照設定にはたくさんのライブラリがありますが、FileSystemObjectを使用するために必要なのは「Microsoft Scripting Runtime」です。

これにチェックを入れて「OK」をクリックします。

参照設定をする場合としない場合の違い

参照設定をした場合、しない場合では次のようなことに違いがあります。

  • 参照設定すると自動コード補完機能が使える
  • 参照設定をしたほうが処理が早い
  • 変数を宣言する部分が違う

自動コード補完機能というのは、「.」を入力したあとにプロパティやメソッドが表示される機能です。

コードの入力ミスを防いでくれるので初心者に優しい機能です。

処理速度についてですが、他のサイトなどを見ていると処理が早くなるとありますが、操作するファイルやフォルダが少なければそれほど気にする必要はないでしょう。

変数の宣言方法については以下を参考にしてください。

参照設定をしたときの宣言方法

Dim fso as FileSystemObject
Set fso = New FileSystemObject

参照設定をした場合は、FileSystemObject型が使用できます。

型を指定したあとに、Newを使って新しくインスタンスを作成します。

参照設定をしないときの宣言

Dim fso asObject
Set fso = CreateObject("Scripting.FileSystemObject")

参照設定しない場合は、Object型で宣言します。

その後、CreateObject関数を使用して、FileSystemObjectを指定します。

まとめ

今回はFileSystemObjectのメソッドを使用してファイルを移動させるプロシージャを紹介しました。

フォルダ内のファイルを移動させたり、ファイルがあるかを調べたりするときにFileSystemObjectは活用できます。

以前の実践編で使用したDir関数でも同様のことはできますが、FileSystemObjectはより細かな処理ができるので、フォルダやファイルの操作が発生するときは活用してみてください。