ファイルの詳細情報(メタデータ)を取得する関数

以下は、VBA関数 GetDetailByHeader は、OSの言語設定に依存せず、Windows Explorerが管理するファイルの**詳細情報(メタデータ)**を確実かつ柔軟に取得するための、非常にロバストなヘルパー関数です。

' --------------------------------------------------------------------------------
' Explorer列から日本語/英語ヘッダ名で値を取得
' (複数の候補ヘッダ(ParamArray headers)を順に探し、最初に見つかった値を返す)
' --------------------------------------------------------------------------------
Private Function GetDetailByHeader(ns As Object, item As Object, ParamArray headers()) As String
    Dim i As Long, h As Variant, name As String, val As String
    ' エラーが発生しても処理を中断しない(存在しない列を参照した場合などに備える)
    On Error Resume Next
    
    For Each h In headers ' 候補のヘッダー名(例: "日付", "Date", "日付時刻")を順に試す
        For i = 0 To 400 ' 0から最大400番目までのExplorer列を走査
            ' 列ヘッダー名を取得
            name = ns.GetDetailsOf(Nothing, i)
            
            If Len(name) > 0 Then
                ' 列名が候補名と一致するかをテキスト比較(大文字小文字無視)でチェック
                If StrComp(name, CStr(h), vbTextCompare) = 0 Then
                    ' ヘッダー名が一致したら、その列インデックス(i)を使って項目の値を取得
                    val = ns.GetDetailsOf(item, i)
                    If Len(val) > 0 Then
                        GetDetailByHeader = val ' 値が取得できたらそれを返して関数を終了
                        Exit Function
                    End If
                End If
            End If
        Next i
    Next h
    
    On Error GoTo 0 ' エラーハンドラをリセット
End Function

🔍 GetDetailByHeader 関数の詳しい説明


💡 概要と目的

この関数の主な目的は、Shell.Application オブジェクトの機能を使って、指定されたファイル(item)の特定のメタデータ(例:「撮影日時」や「評価」)を取得することです。

最大の特長は、メタデータの列ヘッダー名がOSの言語(日本語、英語など)やWindowsのバージョンによって変わることに対応するため、複数の候補名(ParamArray headers)を試行錯誤的に検索する点です。

⚙️ 引数

引数名説明
nsObjectShell.Application.Namespace オブジェクト。対象フォルダのExplorerビュー情報を提供します。
itemObjectShell.FolderItem オブジェクト。メタデータを取得したい特定のファイルを指します。
headers()ParamArray検索する列ヘッダー名の候補リスト(例: "日付", "Date taken", "Date")。この関数に可変長で渡されます。

💻 処理の流れ(ステップバイステップ)

1. エラーハンドラの設定

On Error Resume Next
  • Shell.Application の列 (i) には数千のインデックスが存在しますが、0 から 400 の範囲外や、存在しない列を参照しようとするとエラーが発生することがあります。この行でエラーを無視し、処理を続行させます。

2. ヘッダー名の候補をループ

For Each h In headers
  • 関数に渡されたヘッダー名の候補(例: "タグ", "Tags", "Keywords")を、優先度の高い順に一つずつ取り出して処理します。

3. Explorerの全列インデックスを走査

For i = 0 To 400
  • Windows Explorerの詳細表示で利用可能な列には、0 から始まるインデックス番号が割り当てられています。このループでは、メタデータとして一般的に利用されるインデックス番号 0 から 400 までを順番にチェックします。

4. 列ヘッダー名の取得と比較

name = ns.GetDetailsOf(Nothing, i)
If StrComp(name, CStr(h), vbTextCompare) = 0 Then
  • ns.GetDetailsOf(Nothing, i): ここが重要なポイントです。item の代わりに Nothing を渡すことで、その列インデックス(i)に割り当てられたヘッダー名(列名)を取得できます。
  • 取得した列名 (name) が、現在の検索対象のヘッダー候補 (h) と一致するかを StrComp(..., vbTextCompare) で比較します。これは大文字・小文字を無視して比較するため、堅牢性が高まります。

5. 値の取得と関数の終了

val = ns.GetDetailsOf(item, i)
If Len(val) > 0 Then
    GetDetailByHeader = val
    Exit Function
End If
  • ヘッダー名が一致したら、同じ列インデックス(i)を使って、今度はファイル(item)の値を取得します。
  • 取得した値 (val) が空でなければ、その値を関数の戻り値として設定し、Exit Function で即座に処理を終了します。これにより、同じ情報を指す複数の列名が見つかっても、最初に見つかった列の値を優先的に採用します。

6. エラーハンドラのリセット

On Error GoTo 0
  • 関数の処理がすべて終わった後、エラーを無視する設定 (On Error Resume Next) を解除し、通常のエラー処理状態に戻します。

🎯 この関数の重要性

  • 多言語対応: 列名が「撮影日時」の場合も「Date taken」の場合も、複数の候補を試すことで、どの言語環境のWindowsでも目的のメタデータを取得できます。
  • ロバスト性: 列のインデックスはOSやバージョン、フォルダの種類(画像フォルダ、音楽フォルダなど)によって変わることがありますが、この関数はインデックス番号に依存せず、列名をキーにして値を探すため、非常に安定しています。

使用例は、以下を参照

Follow me!