エクセル実践編:フォルダ内のファイルをリスト化&ハイパーリンク設定からデータ取得までの自動化

アイキャッチ VBA

おつかれさまです!

今回は、私が業務でよく使用しているデータ取得のテンプレートを解説します。
このVBAコードを改造することで、さらに便利な動作をさせることも可能です。
ぜひご覧ください。

この記事を見てできるようになること

この記事を読むことで、以下のことができるようになります。

この記事を見てできるようになること
  • フォルダ内のファイル名をエクセルにリスト化し、各セルにハイパーリンクを自動設定します。
  • エクセルファイルからデータを自動取得し、新しいシートにデータを貼り付けるプロセスを自動化します。

どのような動作をするのか?

動作説明

まずは、このエクセルの動作説明についてです。

シートは「管理シート」のみで構成されています。

「ファイル取得ボタン」を押す、指定したフォルダ内のエクセルファイルをすべて取得しセルに表示します。
また、取得を行った「フォルダパス」「ファイルパス」は、ハイパーリンクの設定を行っているため、クリックで開くことができます。

エクセルの外観

今回「サンプル1.xlsx」~「サンプル5.xls」は、以下の表が入っているとします。
※表であれば、何行・何列あっても、どのような形式でも問題ありません。
 表は「A1」セルから始まることを想定しています。

■ サンプル1.xlsx のデータ

サンプル1.xlsxデータ

■ サンプル2.xlsx のデータ

サンプル2.xlsxデータ

「データ転記ボタン」を押す、「レ」を指定しているエクセルの表をすべて取得しセルに転記します。

データを取得した後のエクセル

また、「サンプル1」シートや「サンプル2」シートの中身は、元データの表が転記されます。

■ サンプル1 シートのデータ

サンプル1シートの内容

■ サンプル2 シートのデータ

サンプル2シートの内容

以上が、このエクセルの動作説明となります。

設定内容について

それでは、この動作を行うための設定を紹介します。

セルの表記について

各セルの表記内容は、下記の通りとしてください。

エクセルの設定
  1. A1セルに「ファイル選択」と入力
  2. A2セルに「フォルダパス」と入力
  3. A4セルに「指定フォルダ内に~」と入力
  4. シート名を「管理シート」と変更

セルの表記内容は、各自変更してもらっても構いません
※ シート名は変更したらコードの変更が必要です。
セルの場所だけ変更しないようにしてください。

エクセルの初期設定

ファイル取得ボタンの動作を実現するVBAコード

以下は、ファイル取得ボタンを押した際の一連の動作を自動化するVBAコードです。
※「ファイル取得ボタン」コードのみ実装するだけであれば、エクセルから指定したフォルダのファイルを開くこともできます。

このコードを標準モジュールに転記ください。
※「Module1」や「Module2」どこに保存しても問題ありません。

コードの記載箇所

コード詳細

Option Explicit

'■ Enum設定
Public Enum 行
    パス記載 = 2
    ファイル転記説明 = 4
    ファイル名開始
End Enum

Public Enum 列
    附番 = 1
    ファイル名記載
    パス記載
    レ点 = 6
End Enum

Public Sub ファイル名を取得()
    Dim folderPath As String
    Dim filePath As String
    Dim fileName As String
    Dim i As Long
    Dim lastRow As Long
    Dim MyRange As Range  '//セルの罫線に使用

    '// 初期設定
    '※ファイルダイアログの初期で表示すされるパス
    Const initPath As String = "C:\サンプル"
    
    '// エラー処理
    On Error GoTo ErrLabel
    
    '// ダイアログでフォルダパス取得
    folderPath = get_folderPath(initPath)
    
    '//最終行取得
    lastRow = Cells(Rows.Count, 列.附番).End(xlUp).Row
    
    '// データ削除
    Call delete_Data(lastRow)

    '// 指定フォルダー内のファイルを取得
    filePath = folderPath & "\*.xls*"
    fileName = Dir(filePath, vbHidden Or vbReadOnly)
    
    i = 0
    Do While fileName <> ""
            Cells(行.ファイル名開始 + i, 列.附番) = i + 1 '//附番を記載
            'Cells(行.ファイル名開始 + i, 列.ファイル名記載) = fileName '//ファイル名を記載
            Cells(行.ファイル名開始 + i, 列.レ点) = "レ" '//「レ」を記載

            Set MyRange = Cells(行.ファイル名開始 + i, 列.レ点) '//「レ」を記載するセルの情報を変更
                    MyRange.HorizontalAlignment = xlCenter
                    MyRange.BorderAround LineStyle:=xlContinuous
                    MyRange.Borders.Weight = xlMedium
                    MyRange.Borders.Color = RGB(255, 192, 0)  '//罫線の色
                    MyRange.Interior.Color = RGB(255, 255, 204)  '//セルの色

            ActiveSheet.Hyperlinks.Add anchor:=Cells(行.ファイル名開始 + i, 列.ファイル名記載), _
                                                         Address:=folderPath & "\" & fileName, _
                                                         TextToDisplay:=fileName  '//ハイパーリンク設定
            i = i + 1
            fileName = Dir()
    Loop

    '//再度、最終行取得
    lastRow = Cells(Rows.Count, 列.附番).End(xlUp).Row
    
    '//抜き出したエクセルを並び替え
    Range(Cells(行.ファイル名開始, 列.ファイル名記載), Cells(lastRow, 列.レ点)) _
            .Sort key1:=Cells(行.ファイル名開始, 列.ファイル名記載), order1:=xlAscending

    '// 検索用の「レ」をドロップダウンにする
    Range(Cells(行.ファイル名開始, 列.レ点), Cells(lastRow, 列.レ点)) _
            .Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:="レ"
    
    Exit Sub

ErrLabel:
        Dim msg As String
        msg = "エラー発生: " & Err.Source & vbCrLf & _
                    "エラー番号: " & Err.Number & vbCrLf & _
                    "エラー内容: " & Err.Description & vbCrLf
        MsgBox (msg)

End Sub

Private Sub delete_Data(ByVal lastRow As Long)
    
    If lastRow <> Cells(行.ファイル転記説明, 列.附番).Row Then
            Range(Cells(行.ファイル名開始, 列.附番), Cells(lastRow, 列.レ点)).Clear
    Else
            Columns(Cells(行.ファイル名開始, 列.レ点).Column).Clear
    End If
    
End Sub

Private Function get_folderPath(ByVal initPath As String) As String
    
    With Application.FileDialog(msoFileDialogFolderPicker)
                .InitialFileName = initPath
                .AllowMultiSelect = False

                .Title = "フォルダの選択"
        If .Show = True Then
                'Cells(行.パス記載, 列.パス記載) = .SelectedItems(1) '//ファイル転記箇所が変更となった際はこちらも変更をすること
                ActiveSheet.Hyperlinks.Add anchor:=Cells(行.パス記載, 列.パス記載), _
                                                         Address:=.SelectedItems(1), _
                                                         TextToDisplay:=.SelectedItems(1)
                
                get_folderPath = .SelectedItems(1)
        End If
    End With
End Function

コードのポイント

  1. ファイルダイアログの設定
    • FileDialogを使って、ユーザーがフォルダを選択できるようにします。
  2. ファイルリストの作成とハイパーリンク設定
    • フォルダ内のファイル名を取得し、エクセルシートにリスト化。
      さらに、各ファイル名にハイパーリンクを自動設定します。
  3. セルの書式設定
    • ファイルリストの隣のセルに「レ」を記載し、罫線や背景色などの書式設定を行います。

使用の際に変更が必要なところ

使用の際に、下記場所を設定してください。

エクセルの設定
  1. Public Enum 行 ~ End Enum
    Public Enum 列 ~ End Enum
    • ここに表記されている数値は、行番号・列番号になります。
      エクセルのセル設定で、構成を変更した場合は、こちらも合わせて変更してください。
      ※数値が記載されていない箇所は、「上記の数値+1」となります。
  2. Const initPath As String = “C:\サンプル”
    • このフォルダパスは、ダイアログが表示される際の初期画面になります。
      表示したい画面のパスに変更して下さい。

ボタンの設置

起動ボタンの設置方法は以下の通りです。

ボタンの設置方法
  • 開発タブをクリック
  • 「挿入」から「ボタン(フォームコントロール)」を選択
  • 空白部をクリック
  • 「マクロの登録」から、「ファイル名を取得」をクリック
  • 「OK」をクリック
ボタンの設置方法

以上が、ファイル取得ボタンの動作を行う設定です。


データ取得ボタンの動作を実現するVBAコード

次に、データ取得ボタンを押したときの動作を実現するコードを紹介します。
このコードでは、「レ」を付けたファイルを対象にデータを取得し、管理エクセルに新しいシートとして追加します。

このコードを標準モジュールに転記ください。
※「Module1」や「Module2」どこに保存しても問題ありません。
  私はこのようなとき、あとから見て分かるようにモジュールを分けて保存します。

コードの記載箇所

コード詳細

Option Explicit

Public Sub 別エクセルのデータ取得()
    Dim Ws As Worksheet
    Dim Arr
    Dim folderPath As String
    Dim filePath As String
    Dim fileName As String
    Dim firstRow As Long, lastRow As Long
    Dim i As Long, j As Long
    
    '//初期設定
    Const init_fileName = "管理シート"
    
    With Sheets(init_fileName)
            
            If .Cells(行.ファイル名開始, 列.附番) = "" Then
                    MsgBox ("データがありません。" & vbCrLf & "ファイルを取得して下さい。")
                    Exit Sub
            End If
            
            firstRow = .Cells(行.ファイル名開始, 列.レ点).Row
            lastRow = .Cells(Rows.Count, 列.レ点).End(xlUp).Row
            folderPath = .Cells(行.パス記載, 列.パス記載) & "\"
            
            Call delete_Sheet(init_fileName)  '//シートを消す
            
            j = 0
            For i = firstRow To lastRow
                    If .Cells(i, 列.レ点) <> "レ" Then GoTo Continue
                    
                    fileName = .Cells(i, 列.ファイル名記載)
                    filePath = folderPath & fileName
                    
                    Arr = get_Arr(filePath)  '// 配列にファイル情報を取得
                    
                    Call create_Sheet(init_fileName, fileName)
                    
                    With Sheets(Sheets.Count)
                            Range(.Cells(1, 1), .Cells(UBound(Arr, 1), UBound(Arr, 2))) = Arr
                    End With
Continue:
            Next i
            .Select
    End With
End Sub

Private Sub delete_Sheet(ByVal init_fileName As String)
    Dim Ws As Worksheet
    
    Application.DisplayAlerts = False
    
    For Each Ws In ThisWorkbook.Sheets
            If Ws.Name <> init_fileName Then
                    Ws.Delete
            End If
    Next Ws

    Application.DisplayAlerts = True
End Sub

Private Function get_Arr(ByVal filePath As String)
    Dim Wb As Workbook
    
    Application.ScreenUpdating = False
    
    Set Wb = Workbooks.Open(fileName:=filePath, ReadOnly:=True)  '//ファイルを開く
    get_Arr = Wb.Sheets(1).Range("A1").CurrentRegion  '//表を取得
    Wb.Close SaveChanges:=False  '//ファイルを閉じる
    
    Application.ScreenUpdating = True
End Function

Private Sub create_Sheet(ByVal init_fileName As String, ByVal fileName As String)
    Dim Ws As Worksheet
    Dim newWs As Worksheet
    Dim file As String
    
    file = Mid(fileName, 1, InStr(fileName, ".") - 1)  '//拡張子を除いたものをシート名にする
    
    Set newWs = Sheets.Add(After:=Worksheets(Worksheets.Count))
    newWs.Name = file
End Sub
コードのポイント
  1. 「レ」を付けたファイルのみを対象にデータ取得
    • If .Cells(i, 列.レ点) <> “レ” Then GoTo Continue の部分で、選択されたファイルのみを処理します。
  2. 開いたエクセルファイルからのデータ取得
    • Workbooks.Openでファイルを開き、シート1のデータを配列に取得します。
  3. 新しいシートの作成とデータ貼り付け
    • 管理エクセルに新しいシートを作成し、取得したデータを貼り付けます。

使用の際に変更が必要なところ

使用の際に、下記場所を設定してください。

エクセルの設定
  1. Const init_fileName = “管理シート”
    • ここに表記されている名称は、シート名になります。
      操作シートの名称を変更した場合は、名称を合わせてください。

ボタンの設置

起動ボタンの設置方法は以下の通りです。

ボタンの設置方法
  • 開発タブをクリック
  • 「挿入」から「ボタン(フォームコントロール)」を選択
  • 空白部をクリック
  • 「マクロの登録」から、「別エクセルのデータ取得」をクリック
  • 「OK」をクリック
ボタンの設置方法

以上が、データ取得ボタンの動作を行う設定です。

コードで使用している機能一覧

このコードで使用している主なVBA機能を以下に一覧でまとめます。

このコードで使っている機能一覧
  • Enum(列挙型)
  • FileDialog(ファイルダイアログ)
  • Const(定数)
  • Dir関数
  • Hyperlinks.Add(ハイパーリンク追加)
  • Range.Validation.Add(入力規則の追加)
  • Workbooks.Open(ブックを開く)
  • Range.CurrentRegion(セル範囲の取得)

これらの機能を使いこなすことで、エクセルでのファイル管理やデータ処理を効率化できます。

まとめ

今回のおさらい

もう一度、エクセルの設定を記載しますね。

1. エクセルは、次のように記載してください。

エクセルの初期設定

2. VBAコードは次のように記載してください。
  ※コードを2つまとめているため、すべてコピペで問題ありません。

Option Explicit

'■ Enum設定
Public Enum 行
    パス記載 = 2
    ファイル転記説明 = 4
    ファイル名開始
End Enum

Public Enum 列
    附番 = 1
    ファイル名記載
    パス記載
    レ点 = 6
End Enum

Public Sub ファイル名を取得()
    Dim folderPath As String
    Dim filePath As String
    Dim fileName As String
    Dim i As Long
    Dim lastRow As Long
    Dim MyRange As Range  '//セルの罫線に使用

    '// 初期設定
    '※ファイルダイアログの初期で表示すされるパス
    Const initPath As String = "C:\サンプル"
    
    '// エラー処理
    On Error GoTo ErrLabel
    
    '// ダイアログでフォルダパス取得
    folderPath = get_folderPath(initPath)
    
    '//最終行取得
    lastRow = Cells(Rows.Count, 列.附番).End(xlUp).Row
    
    '// データ削除
    Call delete_Data(lastRow)

    '// 指定フォルダー内のファイルを取得
    filePath = folderPath & "\*.xls*"
    fileName = Dir(filePath, vbHidden Or vbReadOnly)
    
    i = 0
    Do While fileName <> ""
            Cells(行.ファイル名開始 + i, 列.附番) = i + 1 '//附番を記載
            'Cells(行.ファイル名開始 + i, 列.ファイル名記載) = fileName '//ファイル名を記載
            Cells(行.ファイル名開始 + i, 列.レ点) = "レ" '//「レ」を記載

            Set MyRange = Cells(行.ファイル名開始 + i, 列.レ点) '//「レ」を記載するセルの情報を変更
                    MyRange.HorizontalAlignment = xlCenter
                    MyRange.BorderAround LineStyle:=xlContinuous
                    MyRange.Borders.Weight = xlMedium
                    MyRange.Borders.Color = RGB(255, 192, 0)  '//罫線の色
                    MyRange.Interior.Color = RGB(255, 255, 204)  '//セルの色

            ActiveSheet.Hyperlinks.Add anchor:=Cells(行.ファイル名開始 + i, 列.ファイル名記載), _
                                                         Address:=folderPath & "\" & fileName, _
                                                         TextToDisplay:=fileName  '//ハイパーリンク設定
            i = i + 1
            fileName = Dir()
    Loop

    '//再度、最終行取得
    lastRow = Cells(Rows.Count, 列.附番).End(xlUp).Row
    
    '//抜き出したエクセルを並び替え
    Range(Cells(行.ファイル名開始, 列.ファイル名記載), Cells(lastRow, 列.レ点)) _
            .Sort key1:=Cells(行.ファイル名開始, 列.ファイル名記載), order1:=xlAscending

    '// 検索用の「レ」をドロップダウンにする
    Range(Cells(行.ファイル名開始, 列.レ点), Cells(lastRow, 列.レ点)) _
            .Validation.Add Type:=xlValidateList, AlertStyle:=xlValidAlertStop, Formula1:="レ"
    
    Exit Sub

ErrLabel:
        Dim msg As String
        msg = "エラー発生: " & Err.Source & vbCrLf & _
                    "エラー番号: " & Err.Number & vbCrLf & _
                    "エラー内容: " & Err.Description & vbCrLf
        MsgBox (msg)

End Sub

Private Sub delete_Data(ByVal lastRow As Long)
    
    If lastRow <> Cells(行.ファイル転記説明, 列.附番).Row Then
            Range(Cells(行.ファイル名開始, 列.附番), Cells(lastRow, 列.レ点)).Clear
    Else
            Columns(Cells(行.ファイル名開始, 列.レ点).Column).Clear
    End If
    
End Sub

Private Function get_folderPath(ByVal initPath As String) As String
    
    With Application.FileDialog(msoFileDialogFolderPicker)
                .InitialFileName = initPath
                .AllowMultiSelect = False

                .Title = "フォルダの選択"
        If .Show = True Then
                'Cells(行.パス記載, 列.パス記載) = .SelectedItems(1) '//ファイル転記箇所が変更となった際はこちらも変更をすること
                ActiveSheet.Hyperlinks.Add anchor:=Cells(行.パス記載, 列.パス記載), _
                                                         Address:=.SelectedItems(1), _
                                                         TextToDisplay:=.SelectedItems(1)
                
                get_folderPath = .SelectedItems(1)
        End If
    End With
End Function

Public Sub 別エクセルのデータ取得()
    Dim Ws As Worksheet
    Dim Arr
    Dim folderPath As String
    Dim filePath As String
    Dim fileName As String
    Dim firstRow As Long, lastRow As Long
    Dim i As Long, j As Long
    
    '//初期設定
    Const init_fileName = "管理シート"
    
    With Sheets(init_fileName)
            
            If .Cells(行.ファイル名開始, 列.附番) = "" Then
                    MsgBox ("データがありません。" & vbCrLf & "ファイルを取得して下さい。")
                    Exit Sub
            End If
            
            firstRow = .Cells(行.ファイル名開始, 列.レ点).Row
            lastRow = .Cells(Rows.Count, 列.レ点).End(xlUp).Row
            folderPath = .Cells(行.パス記載, 列.パス記載) & "\"
            
            Call delete_Sheet(init_fileName)  '//シートを消す
            
            j = 0
            For i = firstRow To lastRow
                    If .Cells(i, 列.レ点) <> "レ" Then GoTo Continue
                    
                    fileName = .Cells(i, 列.ファイル名記載)
                    filePath = folderPath & fileName
                    
                    Arr = get_Arr(filePath)  '// 配列にファイル情報を取得
                    
                    Call create_Sheet(init_fileName, fileName)
                    
                    With Sheets(Sheets.Count)
                            Range(.Cells(1, 1), .Cells(UBound(Arr, 1), UBound(Arr, 2))) = Arr
                    End With
Continue:
            Next i
            .Select
    End With
End Sub

Private Sub delete_Sheet(ByVal init_fileName As String)
    Dim Ws As Worksheet
    
    Application.DisplayAlerts = False
    
    For Each Ws In ThisWorkbook.Sheets
            If Ws.Name <> init_fileName Then
                    Ws.Delete
            End If
    Next Ws

    Application.DisplayAlerts = True
End Sub

Private Function get_Arr(ByVal filePath As String)
    Dim Wb As Workbook
    
    Application.ScreenUpdating = False
    
    Set Wb = Workbooks.Open(fileName:=filePath, ReadOnly:=True)  '//ファイルを開く
    get_Arr = Wb.Sheets(1).Range("A1").CurrentRegion  '//表を取得
    Wb.Close SaveChanges:=False  '//ファイルを閉じる
    
    Application.ScreenUpdating = True
End Function

Private Sub create_Sheet(ByVal init_fileName As String, ByVal fileName As String)
    Dim Ws As Worksheet
    Dim newWs As Worksheet
    Dim file As String
    
    file = Mid(fileName, 1, InStr(fileName, ".") - 1)  '//拡張子を除いたものをシート名にする
    
    Set newWs = Sheets.Add(After:=Worksheets(Worksheets.Count))
    newWs.Name = file
End Sub

3. コードの初期設定を行ってください。

エクセルの設定
  1. Public Enum 行 ~ End Enum
    Public Enum 列 ~ End Enum
    • ここに表記されている数値は、行番号・列番号になります。
      エクセルのセル設定で、構成を変更した場合は、こちらも合わせて変更してください。
      ※数値が記載されていない箇所は、「上記の数値+1」となります。
  2. Const initPath As String = “C:\サンプル”
    • このフォルダパスは、ダイアログが表示される際の初期画面になります。
      表示したい画面のパスに変更して下さい。
  3. Const init_fileName = “管理シート”
    • ここに表記されている名称は、シート名になります。
      操作シートの名称を変更した場合は、名称を合わせてください。

これを行うことで、動作をさせることができるようになります。

さらに学ぶために

今回紹介したVBAコードを使うことで、エクセルを使用した業務を大幅に効率化することができます。

ファイル取得とデータ取得の自動化を実現することで、日々の業務負担を軽減し、生産性を向上させましょう。

この記事を参考に、自分の業務に合わせたVBAコードを作成してみてください。

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