エクセルVBA FileSystemObjectのCreateObject・FolderExists・GetFolder

先日お話ししました

参照:指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)

のFileSystemObjectの説明です。

処理の流れのおさらい

  1. セルB3に、フォルダ・サブフォルダ・ファイル名を取得したいフォルダのパスを入力
  2. セルB6に、一覧表を作りたいセル範囲の左上のセルアドレスを入力
  3. <フォルダ・ファイル名一覧作成>ボタンをクリック
    ↓↓↓
    セルB6に入力したアドレスに、ファイル・フォルダ一覧表が完成

エクセルVBA FileSystemObjectのCreateObject・FolderExists・GetFolder

エクセルVBA FileSystemObjectのCreateObject・FolderExists・GetFolder

エクセルVBA FileSystemObjectのCreateObject・FolderExists・GetFolder

プロシージャ

先日作成したプロシージャは下記の通りです。
FileSystemObjectオブジェクトとは?
今回のミッションはフォルダ名やファイル名の取得、ということもあり、至る所でFileSystemObjectオブジェクトが登場しています。(下記コードオレンジ色部
(変数「FSO」にセットしています。)

'【変数】
Dim s_row As Long '開始行
Dim s_col As Long '開始列
Dim e_col As Long '終了列

Sub 指定したフォルダ内の全階層のフォルダ名とファイル名で一覧作成()
    '【変数】
    'ファイル・シート関連関連
    Dim FSO As Object   'FileSystemObject
    Dim pt As String    '対象フォルダパス
    '行列関連
    Dim t_row As Long   '対象行
    Dim t_col As Long   '対象列

    Application.ScreenUpdating = False '画面表示の停止

    '■変数セット
    s_row = Range(Range("B6")).Row    '開始行
    s_col = Range(Range("B6")).Column '開始行
    t_row = s_row + 1                 '対象行
    t_col = s_col                     '対象列
    e_col = t_col                     '最終列

    '■FileSystemObjectのインスタンス化
    Set FSO = CreateObject("Scripting.FileSystemObject")

    '■対象フォルダパス(最後に「\」が無ければ「\」を付ける)
    If Right(pt, 1) = "\" Then
        pt = Range("B3")
    Else
        pt = Range("B3") & "\"
    End If

    '■対象フォルダの有無の確認
    If Not FSO.FolderExists(pt) Then
        MsgBox ("ご指定のフォルダは存在しません。")
        Exit Sub
    End If

    '■前回データのクリア
    Rows(s_row & ":" & Cells.Rows.Count).Clear

    '■再帰処理開始
    Call フォルダファイル名取得(FSO, pt, t_row, t_col)

    '■列幅の調整
    Range(Columns(t_col), Columns(Columns.Count)).ColumnWidth = 3
    Range(Columns(e_col), Columns(e_col + 2)).EntireColumn.AutoFit

    '■サイズ、更新日時の罫線設定
    Range(Cells(s_row, e_col + 1), Cells(t_row - 1, e_col + 1)).BorderAround Weight:=xlHairline, LineStyle:=xlContinuous
    Range(Cells(s_row, t_col), Cells(t_row - 1, e_col + 2)).BorderAround LineStyle:=xlContinuous

    '■見出し設定
    Cells(s_row, s_col) = "フォルダ・ファイル名"
    Cells(s_row, e_col + 1) = "サイズ"
    Cells(s_row, e_col + 2) = "更新日時"
    Range(Cells(s_row, e_col + 1), Cells(s_row, e_col + 2)).HorizontalAlignment = xlCenter

    Application.Goto reference:=Range("A1"), scroll:=True
    Range(Range("B3"), Range("XFD2")).ClearFormats

    '■オブジェクトの解放
    Set FSO = Nothing

    Application.ScreenUpdating = False '画面表示の再開

End Sub

Sub フォルダファイル名取得(FSO As Object, pt As String, t_row As Long, t_col As Long)

    '【変数】
    Dim s_fd As Object 'サブフォルダ
    Dim fl As Object   'ファイル
    Dim strSplit() As String

    '■最終列が増えた場合、サイズ列の前に1列追加
    If t_col > e_col Then
        Columns(t_col).Insert Shift:=xlToRight
        e_col = t_col
    End If

    '■サブフォルダの取得
    For Each s_fd In FSO.GetFolder(pt).SubFolders '変数s_fdに対象フォルダ内のサブフォルダを順に取得
        '□サブフォルダ名転記
        Cells(t_row, t_col) = s_fd.Name

        '□サブフォルダにハイパーリンクを設定
        ActiveSheet.Hyperlinks.Add _
            Anchor:=Cells(t_row, t_col), _
            Address:=s_fd.Path, _
            TextToDisplay:=s_fd.Name

        '□サブフォルダ名罫線設定
        Call 罫線(t_row, t_col)

        t_row = t_row + 1

        '□再帰処理
        Call フォルダファイル名取得(FSO, s_fd.Path, t_row, t_col + 1)
    Next s_fd

    '■ファイル名の取得
    For Each fl In FSO.GetFolder(pt).Files

        '□ファイル名転記
        Cells(t_row, t_col) = fl.Name

        '■Excel・csvファイルはハイパーリンク設定
        strSplit = Split(fl.Path, ".")

        If UBound(strSplit) > 0 Then
            Select Case LCase(strSplit(UBound(strSplit)))
                Case "xls", "xlsx", "xlsm", "csv"
                    ActiveSheet.Hyperlinks.Add _
                        Anchor:=Cells(t_row, t_col), _
                        Address:=fl.Path, _
                        TextToDisplay:=fl.Name
            End Select
        End If

        '□ファイルサイズ・更新日時転記
        Cells(t_row, e_col + 1) = WorksheetFunction.RoundUp(fl.Size / 1024, 0)
        Cells(t_row, e_col + 1).NumberFormatLocal = "#,##0 ""KB"""
        Cells(t_row, e_col + 2) = fl.DateLastModified
        Cells(t_row, e_col + 2).NumberFormatLocal = "yyyy/mm/dd hh:mm:ss"

        '■ファイル名罫線
        Call 罫線(t_row, t_col)

        t_row = t_row + 1
    Next fl

    '■オブジェクトの解放
    Set s_fd = Nothing
    Set fl = Nothing

End Sub

Sub 罫線(t_row As Long, t_col As Long)

    '■左の罫線
    If t_col > s_col Then
        With Range(Cells(t_row, s_col), Cells(t_row, t_col - 1))
            .Borders(xlEdgeLeft).LineStyle = xlContinuous
            .Borders(xlInsideVertical).LineStyle = xlContinuous
        End With
    End If

    '■上の罫線
    With Range(Cells(t_row, t_col), Cells(t_row, e_col + 2))
        .Borders(xlEdgeLeft).LineStyle = xlContinuous
        .Borders(xlEdgeTop).LineStyle = xlContinuous
    End With

End Sub

以前、

参照:CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得

でもお話ししましたが、再度こちらでもご説明いたします。

■■■スポンサーリンク■■■

FileSystemObject

ファイルやフォルダは、セルやシートと違って、Excel上には存在しない外部オブジェクトです。

Excelでは、「FileSystemObject」というオブジェクトを使って、ファイルやフォルダを操作する(作成、削除、移動、コピー等)ことができます。

FileSystemObject」を使用するには、下記の何れかの方法で準備をする必要があります。

  • CreateObject 関数を利用する方法
  • 参照設定を利用する方法

参考:FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止

今回はCreateObject 関数を使用します。

CreateObject関数

CreateObject関数を利用することで、FileSystemObjectを使うことができるようになります。

【CreateObject 関数の利用方法】

Dim FSO As Object
Set FSO = CreateObject("Scripting.FileSystemObject")

***変数「FSO」を利用した処理***

Set FSO = Nothing
  1. まず、変数「FSO」をObjectとして宣言します。
    参照設定をしていないので、「FileSystemObject」への宣言はできません。

    Dim FSO As Object

  2. 次に、CreateObject関数を利用して、変数「FSO」にFileSystemObjectをセットします。

    Set FSO = CreateObject(“Scripting.FileSystemObject”)


    この記述をすることで、変数「FSO」をFileSystemObjectとして使うことができます。

    例1:FSO.FolderExists(フォルダパス)→フォルダ存在の確認します。
            If Not FSO.FolderExists(pt) Then

    例2:FSO.GetFolder(フォルダパス)→フォルダー オブジェクトを返します。
            For Each s_fd In FSO.GetFolder(pt).SubFolders

    例3:Callステートメントで引数として渡すことができます。
            Call フォルダファイル名取得(FSO, pt, t_row, t_col) 
     
  3. 処理の最後に、変数「FSO」を解放します。

    Set FSO = Nothing

CreateObject関数ではなく参照設定を利用する方法もあります。しかし、参照設定では、バージョンの違いでエラーが出ることがあります。
私が業務で作る場合は、色々なPC環境で色々な方が使用することが多いので、参照設定は使用しないようにしています。

CreateObject関数参照設定の違いにつきましては

参照:FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止

をご参照ください。

FolderExistsメソッド

指定したフォルダが存在するかどうかを確認します。

FileSystemObject.FolderExists(パスを含むフォルダ名)

引数(パスを含むフォルダ名)に指定したフォルダが存在する場合は「True」を、存在しない場合は「False]を返します。

If Not FSO.FolderExists(pt) Then

変数「pt」に「C:\VBA\」というフォルダパスがセットされている場合、

「C:\VBA\」フォルダが存在する場合、「True」が返ります。

しかし、今回は「Not」が前に付いていますので、

「C:\VBA\」フォルダが存在しない場合に「True」が返ります。

GetFolderメソッド

指定したパスのフォルダーオブジェクトを返します。

【SubFoldersプロパティ】

フォルダーオブジェクトには、対象のフォルダのサブフォルダを取得するSubFoldersプロパティがあります。

フォルダーオブジェクト.SubFolders

今回は、For Eachを使って、変数「s_fd」に対象フォルダ(変数ptにセットされたパスのフォルダ)のサブフォルダを順番に格納する処理しています。

For Each s_fd In FSO.GetFolder(pt).SubFolders
・
・
Next s_fd

変数「s_fd」にサブフォルダを格納することで、下記のように情報を得ることができます。

s_fd.Name:サブフォルダ名の取得
s_fd.Path:サブフォルダのパス


【Filesプロパティ】

フォルダーオブジェクトには、フォルダ内に存在する全てのファイルオブジェクトを返すFilesプロパティがあります。

フォルダーオブジェクト.Files

今回は、For Eachを使って、変数「fl」に対象フォルダ内(変数ptにセットされたパスのフォルダ)のファイルオブジェクトを順番に格納する処理しています。

For Each fl In FSO.GetFolder(pt).Files
・
・
Next fl

変数「fl」にファイルオブジェクトを格納することで、下記のように情報を得ることができます。

fl.Name:ファイル名
fl.Path:ファイルのパス
fl.Size:ファイルのサイズ
fl.DateLastModified:ファイルの更新日時

Excelとは無関係のファイルやフォルダの操作もできちゃうって・・・。

Excelってすごいですね♪

【参考】

指定したフォルダ内のファイル名全てを取得(Excel VBA)
変数でよく使われる「buf」「tmp」の意味
Dir関数が取得するファイルの順番
指定したフォルダ内のフォルダ名全てをGetAttrを使って「エラー53 ファイルが見つかりません。」を出さずに取得(Excel VBA)
GetAttr関数とAnd演算子でビット演算の使い方 ファイルやフォルダの属性を取得
フォルダ名だけを取得したい時に出てくる 「.」 と 「..」 とは?
指定したフォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
CreateObject(“Scripting.FileSystemObject”) を使ってサブフォルダを取得
再帰処理とは?フォルダ内とサブフォルダ内全てのファイル名を取得(Excel VBA)
指定したフォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
再帰処理とは?フォルダ内のサブフォルダのフォルダ名を全部取得(Excel VBA)
参照渡し「ByRef」と値渡し「ByVal」の違い(Excel VBA)
ファイルのフルパスからファイル名のみを取得 InStrRev関数(Excel VBA)
指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
FileSystemObjectとは?CreateObject 関数 FolderExists・GetFolderの使い方
FileSystemObject CreateObject関数を使う方法・ 参照設定を使う方法 違いを理解してエラー防止
再帰処理とは?指定したフォルダの全ての階層のフォルダ名・サブフォルダ名・ファイル名を取得(Excel VBA)
ファイルのフルパスからファイル名のみを取得 Split関数(Excel VBA)
Callステートメントとは 引数 括弧()の使い方(Excel VBA)
指定したフォルダ内から「特定の文字を含まないファイル名」を取得(Excel VBA)
ワイルドカードとは。使い方いろいろ。(Excel)
Dir関数の使い方。ファイル名やフォルダ名の取得方法。(Excel VBA)
指定したフォルダのファイル名を取得し、そのファイル名を一括で変換(Excel VBA)
Excel起動時に「コンパイルエラー」。64ビット システムで Declareステートメントに、PtrSafe属性を設定(Excel VBA )
「ファイルを開く」ダイアログボックス から ファイル名を取得(Excel VBA)
「ファイルを開く」ダイアログボックス から 複数 ファイル名を取得(Excel VBA)
指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)
再帰処理とは?指定フォルダ内のサブフォルダ全てをフォルダ構成のみ(空フォルダ)を別フォルダにコピー(Excel VBA)

■■■スポンサーリンク■■■