ファイルの詳細情報(メタデータ)を取得する関数
以下は、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)を試行錯誤的に検索する点です。
⚙️ 引数
| 引数名 | 型 | 説明 |
ns | Object | Shell.Application.Namespace オブジェクト。対象フォルダのExplorerビュー情報を提供します。 |
item | Object | Shell.FolderItem オブジェクト。メタデータを取得したい特定のファイルを指します。 |
headers() | ParamArray | 検索する列ヘッダー名の候補リスト(例: "日付", "Date taken", "Date")。この関数に可変長で渡されます。 |
💻 処理の流れ(ステップバイステップ)
1. エラーハンドラの設定
On Error Resume NextShell.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 Thenns.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やバージョン、フォルダの種類(画像フォルダ、音楽フォルダなど)によって変わることがありますが、この関数はインデックス番号に依存せず、列名をキーにして値を探すため、非常に安定しています。

