【VBA】【再帰】指定フォルダ配下(サブフォルダ含む)の全てのExcelファイルに対して、処理を行う

指定フォルダ配下(サブフォルダ含む)の全ての
 ・xlsxファイル
 ・xlsmファイル
に対し、処理をするVBAコードを記載します!

指定フォルダ配下(サブフォルダ含む)に対する処理の例として、
 ・Excelファイル(xlsx、xlsm)を開く
 ・ファイル名をイミディエイトウィンドウへ出力する
VBAコードを記載します!

可読性や保守性を良くするために
 ・処理を3つに分けて作成
します!

PR

VBAコード

可読性や保守性を良くするために、処理を以下の3つに分けて作成します。

3つの処理
  • メイン処理
    ・役割は「対象フォルダの指定」

  • 指定フォルダ配下(サブフォルダ含む)の全ファイルに対する処理(再帰処理)
    ・役割は
     ・「サブフォルダに対する再帰処理」
     ・「Excelファイルかどうかの判定」

  • Excelファイルに対する処理
    ・役割は「Excelファイルに対する処理」


呼び出し関係は以下です。

呼び出し関係
呼び出し関係


ソースコードは以下です。

'変数の宣言を必須
Option Explicit

'**********************************************************
'メイン処理
'**********************************************************
Sub main()
    
    Dim inputFolder As String
    Dim fso As Object

    'イベント抑止
    Application.EnableEvents = False
    
    '対象フォルダの指定
    inputFolder = "C:\Users\user\Desktop\work"
    
    Set fso = CreateObject("Scripting.FileSystemObject")

    '指定フォルダ配下(サブフォルダ含む)の全ファイルに対する処理(再帰処理)
    Call roopAllFiles(inputFolder, fso)

    '後片付け
    Set fso = Nothing

    'イベント抑止を解除
    Application.EnableEvents = True

End Sub

'**********************************************************
'指定フォルダ配下(サブフォルダ含む)の全ファイルに対する処理(再帰処理)
'**********************************************************
Private Function roopAllFiles(ByVal inputFolder As String, ByVal fso As Object)

    'Excelファイルの拡張子を指定
    Const FILE_TYPE_XLSX As String = "xlsx"
    Const FILE_TYPE_XLSM As String = "xlsm"
    
    Dim folder As Object
    Dim file As Object
    
    'サブフォルダの数だけ再帰
    For Each folder In fso.getFolder(inputFolder).SubFolders
        Call roopAllFiles(folder.Path, fso)
    Next

    'ファイル数分繰り返し
    For Each file In fso.getFolder(inputFolder).Files
        'Excelファイルの場合のみ処理を行う
        If LCase(fso.GetExtensionName(file.Name)) = FILE_TYPE_XLSX Or _
           LCase(fso.GetExtensionName(file.Name)) = FILE_TYPE_XLSM Then
            'Excelファイルに対する処理
            Call execForExcelFile(file)
        End If
    Next

End Function

'**********************************************************
'Excelファイルに対する処理
'**********************************************************
Private Function execForExcelFile(ByVal file As Object)
    
    Dim wk As Workbook
        
    'Excelファイルを以下で開く
    '┗「リンクの更新する/しない」のメッセージを非表示
    '┗「読み取り専用を推奨する/しない」のメッセージを非表示
    '┗「読み取り専用」で開く
    Set wk = Workbooks.Open(Filename:=file.Path, UpdateLinks:=0, IgnoreReadOnlyRecommended:=True, ReadOnly:=True)

    '!!!!!!Excelファイルに対する処理を記載する!!!!!!
    'ここでは例としてイミディエイトウィンドウへ出力する
    Debug.Print "「" + wk.Name & "」を開きました"
    
    'Excelファイルを保存せずに閉じる
    wk.Close SaveChanges:=False
    
End Function

Excelファイルに対する処理を変更したい場合は、
 ・「Excelファイルに対する処理」のみ
を変更するだけで良いです。他の2つの処理は変更不要です。

処理内容を変更したい場合
処理内容を変更したい場合

メイン処理の
 ・開始直後でイベント抑止    ※13行目
 ・終了直前でイベント抑止を解除 ※27行目
とすることで、不用意に処理が停止してしまうことを防止しています。
※Excelファイルにイベント処理「Workbook_Open」が設定されていたとしても、実行されないようにする。

Excelファイルを開く際に
 ・「リンクの更新する/しない」のメッセージを非表示
 ・「読み取り専用を推奨する/しない」のメッセージを非表示
とすることで、不用意に処理が停止してしまうことを防止しています(71行目)。
※Excelファイルを開いた際に上記のメッセージが表示されるようになっていたとしても、表示されないようにする。
※他サイトに記載の方法は、上記の考慮が足りていない場合が多いです。

また「読み取り専用」で開くことで、
 ・ミス等によりExcelファイルを不必要に更新してしまう事故
を防止しています。
※78行目で「Excelファイルを保存せずに閉じる」としているため更新されることは無いですが、念のため。

PR

実行結果

指定フォルダ配下(サブフォルダ含む)のExcelファイル(xlsx、xlsm)のファイル名のみが、
イミディエイトウィンドウに表示されました。

実行結果
実行結果
PR

参考①

上記のVBAコードで使用した以下の詳細は、公式サイトをご確認ください。

●「FileSystemObject」の「getFolderメソッド」
「Folderオブジェクト」を取得します。


●「Folderオブジェクト」の「SubFoldersプロパティ」
配下の全てのフォルダを取得します。


●「Folderオブジェクト」の「Filesプロパティ」
配下の全てのファイルを取得します。



●「FileSystemObject」の「GetExtensionNameメソッド」
ファイルの拡張子を取得します。


●「Workbooksオブジェクト」の「Openメソッド」
Excelファイルを開きます。様々なオプションがあります。


●「Workbooksオブジェクト」の「Closeメソッド」
Excelファイルを閉じます。


●イミディエイトウィンドウへ出力


PR

参考②

再帰処理を利用したVBAコードとして以下もあります。

必要に応じて参考としてご確認ください。