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

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

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

可読性を良くするために、処理は3つに分けて作成します!

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

'**********************************************************
'指定フォルダ配下(サブフォルダ含む)の全ファイルに対する処理(再帰処理)
'**********************************************************
Public Function roopAllFiles(inputFolder As String, 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(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つの処理は変更不要です。

メイン処理の
 ・開始直後でイベント抑止
 ・終了直前でイベント抑止を解除
とすることで、不用意に処理が停止してしまうことを防止しています。
※Excelファイルを開いた際にイベント処理が実行される可能性を考慮。

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

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

実行結果

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

タイトルとURLをコピーしました