【VBA】フォルダを作成してその中に保存する(ファイルシステムオブジェクト)

エクセルVBAでよく使うコードの備忘録。ワークブックを保存する際にフォルダが存在しなければ自動で作成してその中にファイルを保存するコード。複数階層のフォルダを一括で作成するコードについても一緒に記載してあります。前回はMkDir関数などを使用する場合についてでしたが、今回はファイルシステムオブジェクト(FileSystemObject)を使う方法について。

スポンサーリンク

ファイルシステムオブジェクトを使う

ファイルシステムオブジェクト(FileSystemObject)はウィンドウズのファイルやフォルダに関連する操作や情報を扱うためのオブジェクトです。ファイルシステムオブジェクトを使用すると、フォルダの作成や削除はもちろん、指定したファイルのサイズや作成日時などの情報も取得することができます。

ファイルシステムオブジェクトを使用するには下記のようにまずオブジェクトを宣言し設定をします。

'--- ファイルシステムオブジェクトを設定 ---'
Dim fso As Object
Set fso = CreateObject("Scripting.FileSystemObject")

ファイルシステムオブジェクトを使うと、フォルダの存在有無の確認や作成を行うことが可能です。フォルダを作成するには次のように行います。なお、カッコに囲まれた部分([***])を自分のプログラムに合わせて変更してください。

フォルダを作成する

'--- 作成したいフォルダのパスを格納する変数 ---'
Dim strPath as String
strPath = "[作成フォルダのパス]"

'--- フォルダを作成する ---'
Call fso.CreateFolder(strPath)

このCreateFolderメソッドもMkDir関数と同じように次のようなケースでエラーを返します。

  • 作成するフォルダが既に存在しているとエラーになる
  • 作成先フォルダの親フォルダも存在していないとエラーになる

この問題を解決するにはフォルダが既に存在しているかどうかを判定する必要があります。フォルダの存在判定もFileSystemObjectを使用して行うことが可能です。

フォルダが存在するかどうか判定する

fso.FolderExists(strPath)

フォルダが存在する場合はTRUEを、そうでなければFALSEを返します。

さらに複数階層にわたってフォルダを作成するには、親フォルダのパスを取得する必要があります。こちらもファイルシステムオブジェクトを利用して簡単に取得可能です。前回ご紹介した方法と比べて大きく異なるポイントは、この親フォルダの取得の部分です。前回は親フォルダのパスを取得するのに自作関数を使いましたが、ファイルシステムオブジェクトにはその機能がすでに存在します。

親フォルダを取得する

'--- 親フォルダのパスを格納する変数 ---'
Dim parentPath As String
parentPath = fso.GetParentFolderName(strPath)

これらの関数を使ってフォルダを作成するサンプルコードを紹介します。

サンプルコード

まずはシンプルなものから。カッコに囲まれた部分([***])を自分のプログラムに合わせて変更してください。

フォルダがなければ作成する(単一階層)

Public Sub CreateFolderSingle()

    '--- ファイルシステムオブジェクト ---'
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    '--- 作成したいフォルダのパス ---'
    Dim strPath As String
    strPath = "[作成するフォルダのパス]"
    
    '--- フォルダが存在しない場合のみMkDirで作成 ---'
    If (Not fso.FolderExists(strPath)) Then
    
        Call fso.CreateFolder(strPath)
    
    End If
    
End Sub

次は、複数階層のフォルダを作成するコードです。CreateFolderMultiという関数を再帰的に呼び出してこれを実現しています。

フォルダがなければ作成する(複数階層)

Public Sub CreateFolderTest()
    
    '--- 作成したいフォルダのパス ---'
    Dim strPath As String
    strPath = "[作成するフォルダのパス]"
    
    '--- フォルダを作成する ---'
    Call CreateFolderMulti(strPath)
    
End Sub

'--- 複数階層のフォルダを作成する関数 ---'
Public Sub CreateFolderMulti(strPath As String)
    
    '--- ファイルシステムオブジェクト ---'
    Dim fso As Object
    Set fso = CreateObject("Scripting.FileSystemObject")
    
    '--- 親フォルダのパスを格納する変数 ---'
    Dim parentPath As String
    parentPath = fso.GetParentFolderName(strPath)
    
    '--- 親フォルダが存在しなければ再帰的に呼び出し ---'
    If (Not fso.FolderExists(parentPath)) Then
    
        Call CreateFolderMulti(parentPath)
        
    Else
    
        If (Not fso.FolderExists(strPath)) Then
            Call fso.CreateFolder(strPath)
        End If
    
    End If
    
End Sub