LoginSignup
0
2

More than 5 years have passed since last update.

EXCEL VBA フォルダ階層図作成ツール コード crossfish21

Posted at

コード

シート埋め込みコード

Private Sub CheckSelectFileType_Change()  ' 「出力するファイル種別を指定する」チェックのON/OFF時の処理

    With ThisWorkbook.Worksheets("階層図作成")
        If .CheckSelectFileType.Value = True Then
            .CheckXlsx.Enabled = True
            .CheckXlsm.Enabled = True
            .CheckXls.Enabled = True
            .CheckDocx.Enabled = True
            .CheckDoc.Enabled = True
            .CheckTxt.Enabled = True
            .CheckJpg.Enabled = True
            .CheckPng.Enabled = True
            .CheckPdf.Enabled = True
        Else
            .CheckXlsx.Enabled = False
            .CheckXlsx.Enabled = False
            .CheckXlsm.Enabled = False
            .CheckXls.Enabled = False
            .CheckDocx.Enabled = False
            .CheckDoc.Enabled = False
            .CheckTxt.Enabled = False
            .CheckJpg.Enabled = False
            .CheckPng.Enabled = False
            .CheckPdf.Enabled = False
        End If
    End With

End Sub

メインコード

Option Explicit
Option Base 1

Dim objFSO As FileSystemObject         ' FSO
Const maxRetsu As Long = 200           ' データの入る最大列数
Dim maxDataRetsu As Long               ' データのある最大列
Dim maxDataGyou As Long                ' データのある最大行
Dim wsKaisouzuSakusei As Worksheet     ' 「階層図作成」シート
Dim wsOutput As Worksheet              ' 階層図出力シート
Dim outputGyou As Long                 ' 出力シートの現在行数
Dim strStartPath As String             ' 階層図作成の基点となるフォルダのパス
Dim selectFileType() As String         ' 出力するファイルの種類のうち、選択されたものを格納する配列
Dim pathRetsu As Long                  ' 「パス」を出力する列番号
Dim nameRetsu As Long                  ' 「フォルダ名・ファイル名」を出力する列番号
Dim typeRetsu As Long                  ' 「種別」を出力する列番号
Dim sizeRetsu As Long                  ' 「サイズ」を出力する列番号
Dim lastmodifyRetsu As Long            ' 「最終更新日」を出力する列番号
Dim kaisouStratRetsu As Long           ' 階層図の作成を始める列番号


Sub CreateKaisouzu()  ' 階層図作成処理

    Dim folderRetsu As Long               ' フォルダの場合の出力列
    Dim fileRetsu As Long                 ' ファイルの場合の出力列
    Dim sortString As String              ' パスのソート用文字列
    Dim yenPosition As Long               ' パスの文字列内の「¥」の位置
    Dim i As Long

    Set wsKaisouzuSakusei = ThisWorkbook.Worksheets("階層図作成")
    Set objFSO = CreateObject("Scripting.FileSystemObject")

    Call CheckInput   ' 入力内容チェック処理の呼び出し

    Application.ScreenUpdating = False
    Application.DisplayAlerts = False

    Worksheets.Add   ' 新しいシートを追加し、このシートに階層図を作成
    Set wsOutput = ActiveSheet
    wsOutput.Range(Columns(1), Columns(maxRetsu)).NumberFormatLocal = "@"  ' セルの書式設定を文字列に
    pathRetsu = 0
    nameRetsu = 0
    typeRetsu = 0
    sizeRetsu = 0
    lastmodifyRetsu = 0
    kaisouStratRetsu = 0
    maxDataRetsu = 1

    With wsKaisouzuSakusei   ' 出力する列を設定
        If .Cells(7, 4).Value <> "" Then
            pathRetsu = .Cells(7, 4).Value  ' 「パス」を出力する列番号
        End If
        If .Cells(8, 4).Value <> "" Then
            nameRetsu = .Cells(8, 4).Value  ' 「フォルダ名・ファイル名」を出力する列番号
        End If
        If .Cells(9, 4).Value <> "" Then
            typeRetsu = .Cells(9, 4).Value  ' 「種別」を出力する列番号
        End If
        If .Cells(10, 4).Value <> "" Then
            sizeRetsu = .Cells(10, 4).Value  ' 「パス」を出力する列番号
        End If
        If .Cells(11, 4).Value <> "" Then
            lastmodifyRetsu = .Cells(11, 4).Value  ' 「最終更新日」を出力する列番号
        End If
        If .Cells(12, 4).Value <> "" Then
            kaisouStratRetsu = .Cells(12, 4).Value  ' 階層図の作成を始める列番号
        End If

    End With

    With wsOutput  ' 出力シートのタイトル部の設定
        If pathRetsu <> 0 Then
            .Cells(1, pathRetsu).Value = "Path"
            .Cells(1, pathRetsu).Interior.Color = 15773696
        End If
        If nameRetsu <> 0 Then
            .Cells(1, nameRetsu).Value = "フォルダ名・ファイル名"
            .Cells(1, nameRetsu).Interior.Color = 15773696
        End If
        If typeRetsu <> 0 Then
            .Cells(1, typeRetsu).Value = "種別"
            .Cells(1, typeRetsu).Interior.Color = 15773696
        End If
        If sizeRetsu <> 0 Then
            .Cells(1, sizeRetsu).Value = "サイズ"
            .Cells(1, sizeRetsu).Interior.Color = 15773696
        End If
        If lastmodifyRetsu <> 0 Then
            .Cells(1, lastmodifyRetsu).Value = "最終更新日"
            .Cells(1, lastmodifyRetsu).Interior.Color = 15773696
        End If
        If kaisouStratRetsu <> 0 Then
            .Cells(1, kaisouStratRetsu).Value = "ここから階層図"
            .Cells(1, kaisouStratRetsu).Interior.Color = 49407
        End If

        maxDataRetsu = wsOutput.Cells(1, wsOutput.Columns.Count).End(xlToLeft).Column
        wsOutput.Range(Cells(1, 1), Cells(1, maxDataRetsu)).Columns.AutoFit   ' セル幅の自動調整
    End With

    folderRetsu = kaisouStratRetsu
    fileRetsu = kaisouStratRetsu + 1
    outputGyou = 2

    Call FileFolderSearch(strStartPath, folderRetsu, fileRetsu)  ' ファイル・フォルダの検索処理を呼び出し

    ' パスのソートをする
    If pathRetsu <> 0 And typeRetsu <> 0 Then  ' ソートを実行するのは「パス」と「種別」の出力指定があった場合のみ
        With wsOutput

            .Columns(1).Select
            Selection.Insert   ' ソートのために1列追加
            .Columns(1).NumberFormatLocal = "@"  ' セルの書式設定を文字列に

            outputGyou = 2
            Do While .Cells(outputGyou, pathRetsu).Value <> ""
                .Cells(outputGyou, 1).Value = .Cells(outputGyou, pathRetsu + 1).Value
                sortString = .Cells(outputGyou, 1).Value
                If .Cells(outputGyou, typeRetsu + 1).Value = "File" Then ' 種別がFileだった場合
                    yenPosition = InStrRev(sortString, "\")  ' 文字列の後方から「¥」を検索
                    sortString = Left(sortString, yenPosition) & " " & Right(sortString, Len(sortString) - yenPosition)
                    ' 最後にある「¥」の後に、半角スペースを入れる
                    .Cells(outputGyou, 1).Value = sortString
                End If
                outputGyou = outputGyou + 1
            Loop

            .Range(Cells(2, 1), Cells(maxDataGyou, maxRetsu)).Sort key1:=.Cells(1, 1) ' 加工したパス名を元にソートする
            .Columns(1).Delete

        End With
    End If

    wsOutput.Range(Cells(2, maxDataRetsu + 1), Cells(maxDataGyou, maxRetsu)).Interior.ColorIndex = 0
    ' データの無い部分のセル色を無色に
    wsOutput.Cells(2, 1).Select
    ActiveWindow.FreezePanes = True  ' 1行目で枠固定

    wsOutput.Range(Cells(1, 1), Cells(maxDataGyou, maxDataRetsu)).Borders.LineStyle = True

    If ThisWorkbook.Worksheets("階層図作成").CheckHyperLink.Value = True Then  ' パスにハイパーリンクを付与する場合
        If pathRetsu <> 0 Then
            For i = 2 To maxDataGyou
                wsOutput.Hyperlinks.Add anchor:=wsOutput.Cells(i, pathRetsu), Address:=wsOutput.Cells(i, pathRetsu)
            Next i
        Else
            MsgBox "パスの出力指定がされていないので、ハイパーリンクの付与は実施しません"
        End If
    End If

    wsOutput.Name = "階層図"
    wsOutput.Move  ' 階層図のシートを新規ブックとして切り離し

    Application.ScreenUpdating = True
    Application.DisplayAlerts = True
    MsgBox "完了"

End Sub


Sub FileFolderSearch(strStartPath As String, folderRetsu As Long, fileRetsu As Long) ' ファイル・フォルダの検索を実行

    Dim objFile As Object           ' ファイル
    Dim objFolder As Object         ' フォルダ
    Dim objSubFolder As Object      ' サブフォルダ
    Dim i As Long
    Dim strFileName As String       ' 拡張子を指定したファイル名の文字列
    Dim bolMatch As Boolean         ' 指定ファイル種別に該当しているかどうか

    With objFSO

        Set objFolder = .GetFolder(strStartPath)

        If ThisWorkbook.Worksheets("階層図作成").CheckChangeColor.Value = True Then  ' フォルダとファイルで色分けする場合
            wsOutput.Range(Cells(outputGyou, 1), Cells(outputGyou, maxRetsu)).Interior.Color = 13434777
        End If

        ' フォルダのデータを出力
        If pathRetsu <> 0 Then
            wsOutput.Cells(outputGyou, pathRetsu).Value = .GetFolder(objFolder).Path
        End If
        If nameRetsu <> 0 Then
            wsOutput.Cells(outputGyou, nameRetsu).Value = .GetFolder(objFolder).Name
        End If
        If typeRetsu <> 0 Then
            wsOutput.Cells(outputGyou, typeRetsu).Value = "Folder"
        End If
        If sizeRetsu <> 0 Then
            wsOutput.Cells(outputGyou, sizeRetsu).Value = .GetFolder(objFolder).Size
        End If
        If lastmodifyRetsu <> 0 Then
            wsOutput.Cells(outputGyou, lastmodifyRetsu).Value = .GetFolder(objFolder).DateLastModified
        End If
        If kaisouStratRetsu <> 0 Then
            wsOutput.Cells(outputGyou, folderRetsu).Value = .GetFolder(objFolder).Name
        End If

        If maxDataRetsu < folderRetsu Then  ' 最大データ列の更新
            maxDataRetsu = folderRetsu
        End If

        maxDataGyou = outputGyou


        ' フォルダ内のファイルのデータを出力
        For Each objFile In objFolder.Files

            If ThisWorkbook.Worksheets("階層図作成").CheckSelectFileType.Value = True Then
            ' ファイル種別の指定がある場合
                bolMatch = False
                For i = 1 To UBound(selectFileType) - 1  ' 現在のobjFileが、指定ファイル種別に該当しているかをチェック
                    strFileName = "*" & selectFileType(i)
                    If .GetFile(objFile).Name Like strFileName Then
                        bolMatch = True
                        Exit For
                    End If
                Next i
                If bolMatch = True Then  ' 現在のobjFileが、指定ファイル種別に該当している場合
                    outputGyou = outputGyou + 1
                    maxDataGyou = outputGyou

                    If ThisWorkbook.Worksheets("階層図作成").CheckChangeColor.Value = True Then  ' フォルダとファイルで色分けする場合
                        wsOutput.Range(Cells(outputGyou, 1), Cells(outputGyou, maxRetsu)).Interior.Color = 9961471
                    End If

                    If pathRetsu <> 0 Then
                        wsOutput.Cells(outputGyou, pathRetsu).Value = .GetFile(objFile).Path
                    End If
                    If nameRetsu <> 0 Then
                        wsOutput.Cells(outputGyou, nameRetsu).Value = .GetFile(objFile).Name
                    End If
                    If typeRetsu <> 0 Then
                        wsOutput.Cells(outputGyou, typeRetsu).Value = "File"
                    End If
                    If sizeRetsu <> 0 Then
                        wsOutput.Cells(outputGyou, sizeRetsu).Value = .GetFile(objFile).Size
                    End If
                    If lastmodifyRetsu <> 0 Then
                        wsOutput.Cells(outputGyou, lastmodifyRetsu).Value = .GetFile(objFile).DateLastModified
                    End If
                    If kaisouStratRetsu <> 0 Then
                        wsOutput.Cells(outputGyou, fileRetsu).Value = .GetFile(objFile).Name
                    End If

                    If maxDataRetsu < fileRetsu Then  ' 最大データ列の更新
                        maxDataRetsu = fileRetsu
                    End If

                Else
                    ' 該当していない場合は、何もしない
                End If

            Else  ' ファイル種別の指定が無い場合
                outputGyou = outputGyou + 1
                maxDataGyou = outputGyou

                If ThisWorkbook.Worksheets("階層図作成").CheckChangeColor.Value = True Then  ' フォルダとファイルで色分けする場合
                    wsOutput.Range(Cells(outputGyou, 1), Cells(outputGyou, maxRetsu)).Interior.Color = 9961471
                End If

                If pathRetsu <> 0 Then
                    wsOutput.Cells(outputGyou, pathRetsu).Value = .GetFile(objFile).Path
                End If
                If nameRetsu <> 0 Then
                    wsOutput.Cells(outputGyou, nameRetsu).Value = .GetFile(objFile).Name
                End If
                If typeRetsu <> 0 Then
                    wsOutput.Cells(outputGyou, typeRetsu).Value = "File"
                End If
                If sizeRetsu <> 0 Then
                    wsOutput.Cells(outputGyou, sizeRetsu).Value = .GetFile(objFile).Size
                End If
                If lastmodifyRetsu <> 0 Then
                    wsOutput.Cells(outputGyou, lastmodifyRetsu).Value = .GetFile(objFile).DateLastModified
                End If
                If kaisouStratRetsu <> 0 Then
                    wsOutput.Cells(outputGyou, fileRetsu).Value = .GetFile(objFile).Name
                End If

                If maxDataRetsu < fileRetsu Then  ' 最大データ列の更新
                    maxDataRetsu = fileRetsu
                End If

            End If

        Next objFile

        If ThisWorkbook.Worksheets("階層図作成").CheckSearchSubFolder.Value = True Then  ' サブフォルダも検索する場合
            ' 再帰処理でサブフォルダのデータを出力する
            For Each objSubFolder In objFolder.SubFolders

                outputGyou = outputGyou + 1
                maxDataGyou = outputGyou

                Call FileFolderSearch(objSubFolder.Path, folderRetsu + 1, fileRetsu + 1)  ' ここで自分自身を呼び出す再帰処理

            Next objSubFolder
        Else
            ' 何もしない
        End If

    End With

End Sub


Sub CheckInput()  ' 入力内容のチェック

    Dim outputRetsuShitei() As Long        ' 出力列の指定内容を格納する配列
    Dim i As Long
    Dim j As Long
    Dim bol1 As Boolean

    If objFSO.FolderExists(wsKaisouzuSakusei.Cells(4, 2).Value) = False Then
        MsgBox "指定されたフォルダは存在しません"
        End
    Else
        strStartPath = wsKaisouzuSakusei.Cells(4, 2).Value
        If Right(strStartPath, 1) <> "\" Then  ' パスの最後に¥が無い場合は、¥を付け足す
            strStartPath = strStartPath & "\"
            wsKaisouzuSakusei.Cells(4, 2).Value = wsKaisouzuSakusei.Cells(4, 2).Value & "\"
        End If
    End If

    Erase outputRetsuShitei
    ReDim Preserve outputRetsuShitei(1)
    For i = 1 To 6
        If wsKaisouzuSakusei.Cells(i + 6, 4).Value <> "" Then
            outputRetsuShitei(UBound(outputRetsuShitei)) = wsKaisouzuSakusei.Cells(i + 6, 4).Value  ' 指定された出力列を配列に格納
            ReDim Preserve outputRetsuShitei(UBound(outputRetsuShitei) + 1)
        End If
    Next i

    If outputRetsuShitei(1) = 0 Then
        MsgBox "出力内容の指定が1つもされていません"
        End
    End If

    For i = 1 To UBound(outputRetsuShitei) - 1
        For j = 1 To UBound(outputRetsuShitei) - 1
            If outputRetsuShitei(i) = outputRetsuShitei(j) And i <> j And outputRetsuShitei(i) <> 0 Then
            ' 出力列の指定に重複がある場合
                MsgBox "出力列の指定に重複があります"
                End
            End If
        Next j
    Next i

    ' 「階層図作成開始」の出力指定列が最も大きいことのチェック
    If wsKaisouzuSakusei.Cells(12, 4).Value <> "" Then
        For i = 7 To 11
            If wsKaisouzuSakusei.Cells(i, 4).Value > wsKaisouzuSakusei.Cells(12, 4).Value Then
                MsgBox "「階層図作成開始」の出力指定列は他の指定列よりも大きい列番号にしてください"
                End
            End If
        Next i
    End If

    With ThisWorkbook.Worksheets("階層図作成") ' 出力するファイル種別の指定をチェック

        If .CheckSelectFileType.Value = True Then
            Erase selectFileType
            ReDim Preserve selectFileType(1)
            If .CheckXlsx.Value = True Then
                selectFileType(UBound(selectFileType)) = ".xlsx"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckXlsm.Value = True Then
                selectFileType(UBound(selectFileType)) = ".xlsm"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckXls.Value = True Then
                selectFileType(UBound(selectFileType)) = ".xls"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckDocx.Value = True Then
                selectFileType(UBound(selectFileType)) = ".docx"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckDoc.Value = True Then
                selectFileType(UBound(selectFileType)) = ".doc"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckTxt.Value = True Then
                selectFileType(UBound(selectFileType)) = ".txt"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckPdf.Value = True Then
                selectFileType(UBound(selectFileType)) = ".pdf"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckJpg.Value = True Then
                selectFileType(UBound(selectFileType)) = ".jpg"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If
            If .CheckPng.Value = True Then
                selectFileType(UBound(selectFileType)) = ".png"
                ReDim Preserve selectFileType(UBound(selectFileType) + 1)
            End If

            If selectFileType(1) = "" Then
                MsgBox "「出力するファイル種別を指定する」のチェックが入っていますが、ファイル種別が1つも選択されていません"
                End
            End If
        End If

    End With

End Sub


Sub SelectFolder()  ' フォルダを選択するダイアログを開く

    With Application.FileDialog(msoFileDialogFolderPicker)
        If .Show = True Then
            Cells(4, 2).Value = .SelectedItems(1) & "\"
        Else
            MsgBox "キャンセルされました"
        End If
    End With

End Sub

0
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
2