【ExcelVBA】シート上に設置されたListboxの一覧のファイルを任意のフォルダにコピーする(フォルダ構成はそのまま)

この記事では、シート上に設置されたListboxの一覧のファイルを任意のフォルダにコピーする方法についてご説明します。

【動画】シート上に設置されたListboxの一覧のファイルを任意のフォルダにコピーする実際の動き

本題に入る前に、まずは次の動画をご覧ください。


Listboxの一覧に表示されたファイルを、指定した先のフォルダにコピーしています。

ファイルをコピーする際は、指定した先のフォルダに直にファイルをコピーするのではなく、先にコピー元のフォルダと同じ構成でフォルダを作成してからファイルをコピーしています。

Excelファイルの例

今回は次のExcelファイルを作成しました。

「folderCopyTo」という名前を付けたセルに、コピー先のフォルダを入力します。

ちなみに今回は、マクロを実行するとコピーする対象のファイル名をListboxに登録しています。

7つのファイルがListboxに登録されており、この7つのファイルをコピー先のフォルダ(「folderCopyTo」という名前を付けたセルに入力されたフォルダ)にコピーします。

コードの例

Excelのマクロのコード(例)

Option Explicit

'階層化されたフォルダを一気に作成するAPI関数
Private Declare PtrSafe Function SHCreateDirectoryEx Lib "shell32" Alias _
                                "SHCreateDirectoryExA" ( _
                                ByVal hwnd As Long, _
                                ByVal pszPath As String, _
                                ByVal psa As Long) As Long

Private Sub btn_fileCopy_Click()
    
    Dim cnt             As Long                 'カウンタ
    Dim getPath         As String               'フォルダパス
    Dim copyFldr        As String               'コピーするファイルのフォルダパス
    Dim fso             As FileSystemObject     'FileSystemObjectのインスタンス用変数
    
    'カウンタを初期化する
    cnt = 0
        
    'FileSystemObjectのインスタンスを生成する
    Set fso = New FileSystemObject
    
    If Right(Range("folderCopyTo").Value, 1) <> "\" Then
    
        '入力されたパスの末尾に「\」が付いていない場合に付ける
        getPath = Range("folderCopyTo").Value & "\"
        
    End If
    
    For cnt = 0 To ListBox1.ListCount - 1
    
        'コピーするファイルのフォルダパスを取得する
        copyFldr = Mid(ListBox1.List(cnt, 1), 4, Len(ListBox1.List(cnt, 1)) - 3) & "\"
                    
        'フォルダを作成する
        Call SHCreateDirectoryEx(0&, getPath & copyFldr, 0&)
        
        'ファイルをコピーする
        fso.copyFile ListBox1.List(cnt, 1) & "\" & ListBox1.List(cnt, 2), getPath & copyFldr
        
    Next cnt
    
End Sub

コードの解説

注目すべきコード①

最初に見て頂きたいのは4行目から8行目です。

'階層化されたフォルダを一気に作成するAPI関数
Private Declare PtrSafe Function SHCreateDirectoryEx Lib "shell32" Alias _
                                "SHCreateDirectoryExA" ( _
                                ByVal hwnd As Long, _
                                ByVal pszPath As String, _
                                ByVal psa As Long) As Long

階層化されたフォルダを一気に作成するAPI関数「SHCreateDirectoryEx」の定義を上記のコードで行っています。

今回は、ファイルをコピーするのに、コピー元のフォルダと同じ構成でフォルダを作成したいのですが、一括でフォルダを作成するのにこの「SHCreateDirectoryEx」を使うと便利です。

例えば「C:¥work」のフォルダ配下に、「aaa¥bbb¥ccc」という3階層のフォルダを一括で作成する場合はこの「SHCreateDirectoryEx」を使うことで、「C:¥work¥aaa¥bbb¥ccc」というフォルダが生成されます。

なお、「SHCreateDirectoryEx」を使用している箇所は36行目です。

        'フォルダを作成する
        Call SHCreateDirectoryEx(0&, getPath & copyFldr, 0&)

第2引数にコピーしたいフォルダ(構成)を指定します。

「SHCreateDirectoryEx」を実行すると、コピー元のフォルダと同じ構成でフォルダが生成されます。

注目すべきコード②

最初に見て頂きたいのは30行目から41行目です。

    For cnt = 0 To ListBox1.ListCount - 1
    
        'コピーするファイルのフォルダパスを取得する
        copyFldr = Mid(ListBox1.List(cnt, 1), 4, Len(ListBox1.List(cnt, 1)) - 3) & "\"
                    
        'フォルダを作成する
        Call SHCreateDirectoryEx(0&, getPath & copyFldr, 0&)
        
        'ファイルをコピーする
        fso.copyFile ListBox1.List(cnt, 1) & "\" & ListBox1.List(cnt, 2), getPath & copyFldr
        
    Next cnt

30行目では、Listboxに登録されたデータ件数(ListBox1.ListCount)分のループ処理を行うように指定しています。

33行目ではコピーするファイルのフォルダパスを取得しています。

今回は「C:¥」が不要で「work¥03_tool」だけが欲しいので、33行目で「C:¥」を除いた「work¥03_tool」の文字列を取得しています。

以上、33行目のコードを実行することで、(「C:¥」を除いた)コピーするファイルのフォルダパスが取得できました。

次にフォルダの作成とその作成したフォルダ内にファイルをコピーします。

36行目ではフォルダの作成を、39行目ではファイルのコピーを行います。

フォルダの作成は「SHCreateDirectoryEx」の第2引数に作成したいフォルダを指定して実行します。

ファイルの作成は、fso.copyFileメソッドの第1引数にコピーしたいファイル名をフルパスで、第2引数にはコピー先のフォルダを指定して実行します。

動作確認

マクロ実行前

「folderCopyTo」という名前を付けたセルに、コピー先のフォルダを入力して「ファイルのコピー」のボタンをクリックします。

Listboxには7つのファイルが登録されています。

コピー先のフォルダは下の通りです。(何もファイルがない状態)

マクロ実行後

マクロを実行するとフォルダ構成はそのままに、シート上に設置されたコンボボックスの一覧のファイルを任意のフォルダにコピーされます。

【注意】参照設定が必要です

一つ注意点があるのですが、先ほどのコードを動かすには参照設定が必要です。

参照設定の一覧(下の画像を参考)から次の項目(ライブラリ)にチェックを付けて「OK」ボタンをクリックします。

  1. Windows Script Host Object Model(wshom.ocx)

なぜ必要かというと、Excelのマクロのコードの15行目の「FileSystemObject」というオブジェクトが「wshom.ocx」というファイルを参照するからです。

    Dim fso             As FileSystemObject     'FileSystemObjectのインスタンス用変数

この参照設定をしないと下の画像のエラーが出ますので必ず行う必要があります。

ここでは「wshom.ocx」とは何者かについては記事の本題から逸れてしまうので詳細は割愛しますが、マクロで「FileSystemObject」というオブジェクトを使う場合は参照設定しないと動かない、程度に思って頂ければと思います。

最後に

本記事では、シート上に設置されたListboxの一覧のファイルを任意のフォルダにコピーする方法についてご説明しました。

シート上に設置されたListboxの一覧のファイルを任意のフォルダにコピーしたい場合は参考にしてみてくださいね。

プログラミングのスキルを習得するなら

プログラミングのスキルを習得したい、今のスキルをもっと高めたい、そう考えているなら「プログラミングスクール」がおすすめです。

プログラミングのスキルの基礎を身につけるなら「TechAcademy」で1週間の無料体験があるので、これで「プログラミングの基礎」を学ぶのにおすすめですよ。

→ TechAcademyの「1週間 無料体験」はこちら