【VBA】ファイルの更新日時・サイズ・属性を取得する方法(コピペOK)

VBA
スポンサーリンク
スポンサーリンク

この記事でできること

VBAでファイルの更新日時・サイズ・属性を取得し、シートに一覧出力できるようになる。

対象:VBA初心者〜初級者。「フォルダの中身を手作業で確認するのが面倒」という方向け。

コピペ → 実行まで5分。

どんな場面で使う?

自分がファイル情報の一括取得を使うのは、以下のような場面。どれも「手作業でやると途方もない時間がかかる」系の作業。

  • 共有フォルダのファイル棚卸し:四半期ごとに「どのファイルがいつ更新されたか」を一覧化して、古いファイルの整理方針を決める
  • 納品物の確認作業:外部ベンダーから受け取ったファイル群のサイズや更新日時を一覧にして、仕様通りに揃っているかチェックする
  • バックアップの検証:バックアップ先フォルダのファイルが正しくコピーされたか、更新日時とサイズで照合する
  • 不要ファイルの特定:「90日以上更新されていないファイル」「サイズが0バイトの空ファイル」など条件を付けて、削除候補を洗い出す
  • 読み取り専用ファイルの管理:誰かが読み取り専用に設定したまま戻し忘れたファイルを一括で特定する

自分も以前、共有フォルダに溜まったファイルを「いつ更新されたか」「サイズはどれくらいか」をひとつずつ右クリック → プロパティで確認していた。10個くらいなら我慢できるけど、50個を超えたあたりで正直しんどかった。VBAで一括取得するようにしてからは、数百ファイルでも数秒で一覧が出るようになった。この記事で、同じ作業に時間を取られている人がサクッと自動化できるようになればうれしい。

Before / After

Before(手作業):

  • ファイルを1つずつ右クリック → プロパティ → 更新日時・サイズを目視確認
  • Excelにコピペして一覧を作成 → 50ファイルで30分以上

After(VBA自動化):

  • マクロを実行 → フォルダ内の全ファイルの更新日時・サイズ・属性がシートに一覧出力
  • 数百ファイルでも数秒で完了

手順

  1. Excelを開き、Alt + F11 でVBE(コードを書く画面)を開く
  2. メニューバーの 挿入 → 標準モジュール をクリック
  3. 下のコードをコピーして貼り付ける
  4. F5 キーで実行(またはマクロ実行画面から選択)

前提条件

– Excel 2016以降 / Microsoft 365

– Windows 10/11

– 保存形式:.xlsm(マクロ有効ブック)

– 貼り付け場所:標準モジュール

– 実行方法:マクロ実行(F5 または Alt + F8)

基本コード(単一ファイルの情報取得)

まずは1つのファイルの更新日時・サイズ・属性を取得する最小限のコードから。


Sub GetFileInfo()
    Dim filePath As String
    Dim fileDate As String
    Dim fileSize As Long
    Dim fileAttr As Integer

    ' ★ここにファイルパスを指定
    filePath = "C:\Users\Public\Documents\sample.xlsx"

    ' ファイルの存在確認
    If Dir(filePath) = "" Then
        MsgBox "ファイルが見つかりません。" & vbCrLf & filePath, vbExclamation
        Exit Sub
    End If

    ' 更新日時を取得
    fileDate = FileDateTime(filePath)

    ' ファイルサイズを取得(バイト単位)
    fileSize = FileLen(filePath)

    ' ファイル属性を取得
    fileAttr = GetAttr(filePath)

    ' 結果を表示
    MsgBox "ファイル: " & Dir(filePath) & vbCrLf & _
           "更新日時: " & fileDate & vbCrLf & _
           "サイズ: " & fileSize & " バイト" & vbCrLf & _
           "属性値: " & fileAttr, vbInformation
End Sub

基本コードの詳細解説

このコードでやっていることは4ステップ。まず Dir(filePath) でファイルの存在確認をしている。Dir は指定パスにファイルが存在すればファイル名を返し、存在しなければ空文字を返す。存在しないファイルに FileDateTime や FileLen を実行するとエラーになるので、この事前チェックは必須。ファイル存在確認の詳しい方法はファイルやフォルダの存在を確認してから処理する方法(/074)を参照。

次に FileDateTime(filePath) で最終更新日時を取得する。返り値は文字列型(String)で、「2026/03/24 14:30:00」のような形式。Date 型ではないので、日付として比較したい場合は CDate() で変換する必要がある。

FileLen(filePath) はバイト単位でファイルサイズを返す。KB に変換するなら 1024 で割り、MB なら 1024 で2回割る。Long 型で返るので、2GB を超えるファイルでは正確な値が取れない点に注意(VBA の Long 型の上限は約 2.1GB)。

GetAttr(filePath) はファイル属性をビットフラグの数値で返す。これは少し特殊な仕組みで、複数の属性が合算された数値が返ってくる。判定には And 演算子を使う(後述)。

GetAttrの属性値の意味は以下の通り。

定数 意味
vbNormal 0 標準ファイル
vbReadOnly 1 読み取り専用
vbHidden 2 隠しファイル
vbSystem 4 システムファイル
vbDirectory 16 フォルダ
vbArchive 32 アーカイブ

属性値はビットフラグの合計値になる。たとえば「読み取り専用+隠しファイル」なら 1 + 2 = 3 が返る。判定には And 演算子を使う(実務版で解説)。

実務版コード(フォルダ内全ファイルの属性一覧をシートに出力)

自分はこの方法を覚えてからは、月次の棚卸しで「どのファイルがいつ更新されたか」を一覧化する作業が一瞬で終わるようになった。


Sub ListFileProperties()
    Dim folderPath As String
    Dim fileName  As String
    Dim ws        As Worksheet
    Dim row       As Long
    Dim attr      As Integer

    ' ★ここにフォルダパスを指定(末尾の \ を忘れずに)
    folderPath = "C:\Users\Public\Documents\"

    ' フォルダの存在確認
    If Dir(folderPath, vbDirectory) = "" Then
        MsgBox "フォルダが見つかりません。" & vbCrLf & folderPath, vbExclamation
        Exit Sub
    End If

    ' 出力先シートの準備
    Set ws = ActiveSheet
    ws.Cells.Clear

    ' ヘッダー行を出力
    ws.Range("A1").Value = "ファイル名"
    ws.Range("B1").Value = "更新日時"
    ws.Range("C1").Value = "サイズ(KB)"
    ws.Range("D1").Value = "読取専用"
    ws.Range("E1").Value = "隠しファイル"
    ws.Range("F1").Value = "属性値"
    ws.Range("A1:F1").Font.Bold = True

    row = 2

    ' フォルダ内のファイルを順番に処理
    fileName = Dir(folderPath & "*.*")
    Do While fileName <> ""
        ws.Cells(row, 1).Value = fileName
        ws.Cells(row, 2).Value = FileDateTime(folderPath & fileName)
        ws.Cells(row, 3).Value = Round(FileLen(folderPath & fileName) / 1024, 1)

        ' 属性をビットフラグで判定
        attr = GetAttr(folderPath & fileName)
        ws.Cells(row, 4).Value = IIf((attr And vbReadOnly) > 0, "Yes", "")
        ws.Cells(row, 5).Value = IIf((attr And vbHidden) > 0, "Yes", "")
        ws.Cells(row, 6).Value = attr

        row = row + 1
        fileName = Dir()  ' 次のファイルへ
    Loop

    ' 列幅を自動調整
    ws.Columns("A:F").AutoFit

    MsgBox (row - 2) & " 件のファイル情報を出力しました。", vbInformation
End Sub

実務版コードの詳細解説

このコードのポイントは Dir 関数の「2回呼び」の仕組みにある。最初の Dir(folderPath & "*.*") でフォルダ内の最初のファイル名を取得し、ループ内の Dir() (引数なし)で次のファイル名を順番に取得していく。Dir は内部的に「次のファイル」を覚えているので、引数なしで呼ぶだけで次のファイルに進む。全ファイルを処理し終わると空文字を返すので、Do While fileName <> "" でループが終了する。

属性の判定で (attr And vbReadOnly) > 0 としているのは、ビットフラグの判定テクニック。GetAttr は複数の属性を合算した値を返すため、attr = 1(読み取り専用)と単純比較すると、「読み取り専用 + アーカイブ」(1 + 32 = 33)のようなケースで判定が漏れる。And 演算子を使えば、他の属性が付いていても「読み取り専用かどうか」だけを正確に判定できる。

ファイルサイズは Round(FileLen(...) / 1024, 1) で KB 単位(小数第1位)に変換している。バイト単位のままだと桁数が多くて読みにくいため、実務では KB や MB に変換して出力するのが一般的。フォルダ内ファイル一覧を自動取得する方法(/001)でも同じ Dir 関数の使い方が解説されている。

注意: このマクロはアクティブシートの内容をクリアしてから出力する。大事なデータがあるシートでは実行しないこと。実行前にブックを別名で保存(バックアップ)しておくことを推奨。

実務版コード2(FSO版でより詳細な情報を取得)

VBA組み込み関数では取得できない「作成日時」「最終アクセス日時」も必要な場合は、FileSystemObject(FSO)を使う。FileSystemObjectでサブフォルダを再帰検索してファイル一覧を取得する方法でも使われる技術だ。


Sub ListFilePropertiesFSO()
    Dim fso       As Object
    Dim folder    As Object
    Dim file      As Object
    Dim ws        As Worksheet
    Dim row       As Long
    Dim folderPath As String

    ' ★ここにフォルダパスを指定
    folderPath = "C:\Users\Public\Documents\"

    ' FSOオブジェクトを作成
    Set fso = CreateObject("Scripting.FileSystemObject")

    ' フォルダの存在確認
    If Not fso.FolderExists(folderPath) Then
        MsgBox "フォルダが見つかりません。" & vbCrLf & folderPath, vbExclamation
        Set fso = Nothing
        Exit Sub
    End If

    Set folder = fso.GetFolder(folderPath)

    ' 出力先シートの準備
    Set ws = ActiveSheet
    ws.Cells.Clear

    ' ヘッダー行を出力
    ws.Range("A1").Value = "ファイル名"
    ws.Range("B1").Value = "作成日時"
    ws.Range("C1").Value = "更新日時"
    ws.Range("D1").Value = "最終アクセス日時"
    ws.Range("E1").Value = "サイズ(KB)"
    ws.Range("F1").Value = "種類"
    ws.Range("G1").Value = "属性文字列"
    ws.Range("A1:G1").Font.Bold = True

    row = 2

    ' フォルダ内のファイルを順番に処理
    For Each file In folder.Files
        ws.Cells(row, 1).Value = file.Name
        ws.Cells(row, 2).Value = file.DateCreated
        ws.Cells(row, 3).Value = file.DateLastModified
        ws.Cells(row, 4).Value = file.DateLastAccessed
        ws.Cells(row, 5).Value = Round(file.Size / 1024, 1)
        ws.Cells(row, 6).Value = file.Type

        ' 属性を文字列で表示
        Dim attrStr As String
        attrStr = ""
        If file.Attributes And 1 Then attrStr = attrStr & "読取専用 "
        If file.Attributes And 2 Then attrStr = attrStr & "隠し "
        If file.Attributes And 4 Then attrStr = attrStr & "システム "
        If file.Attributes And 32 Then attrStr = attrStr & "アーカイブ "
        ws.Cells(row, 7).Value = Trim(attrStr)

        row = row + 1
    Next file

    ' 列幅を自動調整
    ws.Columns("A:G").AutoFit

    MsgBox (row - 2) & " 件のファイル情報を出力しました。", vbInformation

    Set folder = Nothing
    Set fso = Nothing
End Sub

FSO版の詳細解説

CreateObject("Scripting.FileSystemObject") は遅延バインディング(レイトバインディング)でFSOを呼び出している。参照設定で「Microsoft Scripting Runtime」を追加する方法もあるが、CreateObject を使えば参照設定なしで動くため、マクロを他のPCに配布するときに「参照設定を追加してください」という手間が省ける。

FSOを使う最大のメリットは、VBA組み込み関数では取得できない「作成日時(DateCreated)」と「最終アクセス日時(DateLastAccessed)」が取れること。file.Type はエクスプローラーで表示される「種類」(例:「Microsoft Excel ワークシート」)を文字列で返してくれるので、拡張子を自分で判定する必要がない。

コード末尾の Set folder = Nothing / Set fso = Nothing はオブジェクトの明示的な解放。VBAはプロシージャ終了時に自動的にオブジェクトを解放するが、大量ファイルを処理した後はメモリを早めに解放しておくほうが安全。特にFSOは内部でファイルハンドルを保持しているので、明示的に Nothing をセットする習慣を付けておくとよい。

Dir 関数版と FSO 版のどちらを使うかの判断基準は「作成日時が必要かどうか」。更新日時とサイズだけでよければ Dir 版のほうがシンプルで高速。作成日時やファイルの種類まで必要なら FSO 版を使う。

この一覧を作った後、古いファイルを自動削除するマクロと組み合わせると、「90日以上更新されていないファイルを一掃」といった運用ができる。出力した一覧をもとにファイルを開いて処理したい場合はファイルを開く・閉じるを自動化する方法(/073)、一覧をCSVとして外部に渡したい場合はCSVファイルを書き出す方法(/019)と組み合わせると便利。

落とし穴

# 症状 原因 対策
1 「ファイルが見つかりません」エラー(実行時エラー 53) ファイルパスの指定ミス。全角のを使っている、パスの末尾に余計なスペースがあるなど パスはエクスプローラーのアドレスバーからコピペする。半角\を使う
2 FileLenが0を返す ファイルが0バイト(空ファイル)の場合、または他のアプリが書き込み中でロックされている 0バイトの場合は正常動作。ロック中の場合はファイルを閉じてから実行する
3 GetAttrの値が想定と違う 属性値はビットフラグの合計値。vbArchive(32)が常に加算されるため、「標準ファイル」でも0ではなく32が返ることが多い If (attr And vbReadOnly) > 0 ThenのようにAnd演算子で個別判定する。値そのものを比較(= 1)しない
4 Dirがサブフォルダ内のファイルを返さない Dir関数は指定フォルダ直下のファイルのみ対象。サブフォルダを再帰的に検索しない サブフォルダも含めたい場合はFSOでサブフォルダを再帰検索する方法を参照
5 FileDateTimeが「最終更新日時」しか返さない VBA組み込みのFileDateTime関数は更新日時のみ対応。作成日時やアクセス日時は取得できない 作成日時が必要な場合はFSO版(file.DateCreated)を使う
6 大量ファイル(数千件)で処理が遅い セルに1つずつ書き込む処理がボトルネック Application.ScreenUpdating = Falseを追加する。さらに高速化したい場合は配列を使ってVBAの処理速度を10倍にする方法を参照

自分もGetAttrの戻り値を = 1 で比較して「読み取り専用のはずなのに判定されない」と30分悩んだことがある。ビットフラグという仕組みを知らなかっただけだったのだが、初心者がハマりやすいポイントだと思う。

VBAでFileDateTimeが取得できない・エラーになるときの対処法

「FileDateTimeを実行したら『ファイルが見つかりません』のエラー53が出る」という場合、原因はファイルパスの指定ミスがほとんどだ。全角の を使っている、パスの末尾に余計なスペースがある、拡張子が違う(.xlsx と .xls の取り違え)などが典型的。対処法は、エクスプローラーのアドレスバーからパスをコピペして使うこと。自分も手入力したパスで何度もハマったが、コピペに切り替えてからはエラーがなくなった。コピペ前に Trim でスペースを除去しておくとより安全。

VBAでファイルの更新日時が取得できない・値がおかしいときの対処法

「FileDateTimeで取得した日時がPCの表示と違う」という場合、原因はFileDateTime関数が返すのは「最終更新日時」だけという仕様にある。「作成日時」や「最終アクセス日時」は取得できない。作成日時が必要な場合は、FileSystemObject(FSO)の file.DateCreated を使う必要がある。また、ネットワークドライブ上のファイルでは、サーバーとPCのタイムゾーン設定の違いで時刻がずれることもある。

VBAでGetAttrの属性判定が正しくできないときの対処法

「GetAttrで読み取り専用を判定しようとしたのに If attr = 1 Then で引っかからない」という場合、原因はGetAttrの戻り値がビットフラグの合計値だからだ。「読み取り専用 + アーカイブ」なら 1 + 32 = 33 が返る。= 1 の単純比較では判定できない。対処法は If (attr And vbReadOnly) > 0 Then のように And 演算子で個別のフラグを取り出すこと。この書き方なら他の属性が同時に設定されていても正確に判定できる。

FAQ

Q1. FileDateTime で取得した日時を「yyyy/mm/dd」形式で表示したい

Format関数を使う。


ws.Cells(row, 2).Value = Format(FileDateTime(filePath), "yyyy/mm/dd hh:nn:ss")

nnは分(mmだと月と区別できないため)。日付や数値の表示形式をFormatで自由に変換する方法も参考にしてほしい。

Q2. ファイルサイズをMB単位で表示するには?

1024で2回割る。


ws.Cells(row, 3).Value = Round(FileLen(filePath) / 1024 / 1024, 2)

Q3. 特定の拡張子(.xlsxだけ)に絞りたい

Dir関数のワイルドカードを変更する。


fileName = Dir(folderPath & "*.xlsx")

Q4. 読み取り専用ファイルだけを抽出したい

GetAttrとAnd演算子で判定する。


If (GetAttr(folderPath & fileName) And vbReadOnly) > 0 Then
    ' 読み取り専用のファイルだけ処理
End If

Q5. フォルダのサイズ(中のファイル合計)を取得したい

FSO版でループしながら合計する。


Dim totalSize As Double
totalSize = 0
For Each file In folder.Files
    totalSize = totalSize + file.Size
Next file
MsgBox "合計: " & Round(totalSize / 1024 / 1024, 2) & " MB"

よくあるエラーと対処法(追加)

上の落とし穴テーブルに加えて、自分が実務で遭遇した追加のエラーパターンも紹介する。

ネットワークドライブのファイルでタイムアウトする

共有フォルダ(\\server\share\ のようなUNCパス)にある大量ファイルの情報を取得すると、ネットワーク遅延で処理が極端に遅くなることがある。自分も500件のファイル情報取得に10分以上かかって焦った経験がある。対策としては、まずローカルにファイルをコピーしてから情報を取得するか、Application.ScreenUpdating = False でExcelの画面更新を止めて処理速度を上げる。また、途中でエラーが起きても処理が止まらないようにエラー処理の応用パターン(リトライ・ログ・通知)を実装する方法(/099)のリトライ処理を入れておくとより安全。

日本語を含むファイル名で文字化けする

通常のVBA関数(Dir / FileDateTime / FileLen / GetAttr)では日本語ファイル名でも問題なく動作する。ただし、テキストファイルにログとして書き出す場合、文字コードの設定によっては文字化けすることがある。ログ出力時はマクロの実行ログをファイルに自動記録する方法(/052)の書き出し方法を参考にしてほしい。

まとめ

この記事では、VBAでファイルの更新日時・サイズ・属性を取得する方法を解説した。

  • 基本コード:FileDateTime・FileLen・GetAttrで単一ファイルの情報を取得
  • 実務版:Dir関数でフォルダ内全ファイルの属性一覧をシートに出力。ビットフラグの And 演算子による属性判定がポイント
  • FSO版:作成日時・最終アクセス日時など、VBA組み込み関数では取得できない詳細情報も取得可能
  • 使い分けの目安:更新日時とサイズだけでよければ基本コード(参照設定不要)、作成日時やファイル種類まで欲しければFSO版を使う

ファイル情報の一覧化は、棚卸しや整理の第一歩。ここから古いファイルの自動削除ファイルやフォルダの存在を確認してから処理する方法(/074)と組み合わせると、ファイル管理を一気に自動化できる。取得した一覧をCSVとして書き出したい場合はCSVファイルを書き出す方法(/019)、一覧にオートフィルタをかけて「読み取り専用だけ」「特定日以降に更新されたものだけ」と絞り込むのも便利。大量ファイルの処理で速度が気になる場合は処理時間を計測してボトルネックを特定する方法(/118)で計測してから最適化するとよい。

次にやりたくなること

コメント

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