このページの目次
画像ファイルや動画ファイルの整理をしたいと思い、撮影日やメディアの作成日を取得するマクロを作りました。
windowsのエクスプローラ画面上で、動画ファイルや画像ファイルを右クリックして「プロパティ」を表示させ、「詳細」タブに表示させる撮影日やメディアの作成日を取得するものです。
画像ファイルは、撮影日に日付が設定されており、動画ファイルは、「メディアの作成日」という項目に情報が入ります。
動作確認している環境は、Windows11になります。
フォルダ参照とファイル名一覧の取得については、別途、記載済みなので、下記の関連記事を参照してください。
上図のA列のファイル名一覧を入力情報に使用します。
以下をVisual Basic画面のシートオブジェクトに記述します。
Sub 撮影日の取得()
'自作クラスを生成
Dim phtinfo As New PhotoInfo
'ファイルパス一覧シート
Dim pathSheet As Worksheet
Dim cnt As Long
Dim endRow As Long
Dim eachRng As Range
Dim filepath As String
'自作クラスの初期化(画像・動画格納フォルダのパス)
Call phtinfo.PhotoInfo_init(ThisWorkbook.Worksheets("実行").Range("B3").Value)
'ファイルパスを受け取るシート名
Set pathSheet = ThisWorkbook.Worksheets("filelist")
'ループ処理
'最終行の取得
endRow = pathSheet.Range("A" & Rows.Count).End(xlUp).Row
'A列の1行目から最終行までループ
For Each eachRng In pathSheet.Range("A1:A" & endRow)
'表示形式設定
eachRng.Offset(0, 1).NumberFormatLocal = "yyyymmdd"
'パスの右隣のセルに撮影日時を出力
eachRng.Offset(0, 1) = phtinfo.Get撮影日時(eachRng.Value)
Next
'画面の更新で完了とする
ThisWorkbook.Worksheets("filelist").Activate
'メモリ解放
Set phtinfo = Nothing
Set pathSheet = Nothing
Set eachRng = Nothing
End Sub
VBAでは、関数名に日本語が使えるため、「Sub 撮影日の取得()」と日本語にしています。
PhotoInfoというクラスを自作し、画像や動画ファイルの撮影日を取得しています。
クラス化させた理由は、画像や動画ファイルの撮影日が記述されている位置情報をクラス内に記憶させたかったからです。
画像や動画ファイルの撮影日が記述されている位置の情報は、ファイルではなく、フォルダから取得できます。その情報を、ファイル毎に取得するのは、処理の重複になるため、初期化処理で位置を保存し、その情報を取得処理(Get撮影日時()関数)で使用しています。
そのため、PhotoInfoを使用するために、初期化処理をまず呼び出し、ファイル毎にGet撮影日時()関数を呼び出しています。
PhotoInfoの初期化処理の引数に設定しているのは、フォルダ参照で設定したフォルダパス格納位置になります。
下記に、PhotoInfoクラスオブジェクトの内容を記述します。
クラスを作成するには、Visual Basic画面のプロジェクトエクスプローラ画面にて右クリックしてクラスを追加してください。
Visual Basic画面のメニュー「表示」->「プロパティウィンドウ」を表示させ、オブジェクト名を「PhotoInfo」に変更する。
下記のコードを動作させるためには、参照設定に「Microsoft Shell Controls And Automation」と「Microsoft Scripting Runtime」の追加が必要です。
まずは、クラスの初期化処理で、「撮影日時」の格納位置を取得します。
'参照設定 Microsoft Shell Controls And Automation
'参照設定 Microsoft Scripting Runtime
Dim 撮影日時位置 As Long '写真なら「撮影日時」
Dim 作成日時位置 As Long '動画なら「メディアの作成日時」(<>「作成日時」とは別物)
Dim 作成日時位置2 As Long '上二つの情報がないものは「作成日時」にする
Function PhotoInfo_init(folderStr As String)
Dim FSO As New FileSystemObject
Dim myShell As New Shell32.Shell
Dim folObj As Object
Dim cnt As Long
'フォルダからEXIF情報(拡張情報)の日本語名を取得
Set folObj = myShell.Namespace(FSO.GetParentFolderName(folderStr))
For cnt = 0 To 330
If folObj.GetDetailsOf(Nothing, cnt) = "撮影日時" Then
撮影日時位置 = cnt
ElseIf folObj.GetDetailsOf(Nothing, cnt) = "メディアの作成日時" Then
作成日時位置 = cnt
ElseIf folObj.GetDetailsOf(Nothing, cnt) = "作成日時" Then
作成日時位置2 = cnt
End If
Next cnt
'メモリ解放
Set FSO = Nothing
Set myShell = Nothing
Set folObj = Nothing
End Function
画像や動画ファイルを格納しているフォルダパスを引数で受け取る。
「撮影日時」と「メディアの作成日」という名前と一致する位置情報を保存する。
クラス型の場合は、関数外に変数を宣言することができます。(クラス内のグローバル変数)特別な変数のため、変数名を日本語にしています。
下記は初期化クラスの下につづけて記述します。
'日付を取得
Function Get撮影日時(path As String) As Date
Dim FSO As New FileSystemObject
Dim myShell As New Shell32.Shell
Dim shFolder As Object
Dim shFile As Object
Dim dateString As String
Set shFolder = myShell.Namespace(FSO.GetParentFolderName(path))
Set shFile = shFolder.ParseName(FSO.GetFileName(path))
If shFolder.GetDetailsOf(shFile, 撮影日時位置) <> "" Then
'撮影日時が空でなければ取得
dateString = shFolder.GetDetailsOf(shFile, 撮影日時位置)
ElseIf shFolder.GetDetailsOf(shFile, 作成日時位置) <> "" Then
'「撮影日時」が未設定なら、「メディアの作成日」を取得
dateString = shFolder.GetDetailsOf(shFile, 作成日時位置)
Else
'上2つが空なら、最終手段の作成日時を取得
dateString = shFolder.GetDetailsOf(shFile, 作成日時位置2)
End If
If IsDate(日時変換(dateString)) = True Then
Get撮影日時 = 日時変換(dateString)
Else
'取得できず
Get撮影日時 = 0
End If
'メモリ解放
Set FSO = Nothing
Set myShell = Nothing
Set shFolder = Nothing
Set shFile = Nothing
End Function
引数でファイルパスを受け取り、初期化処理で取得した、「撮影日位置」や「メディアの作成日」位置情報を元にファイル個別の情報を取得し、戻り値として返します。
GetDetailsOfメソッドで取得できる日付をVBAで日時として処理できるように成型する処理を日時変換に切り出しています。
下記に日時変換()関数を記載します。PhotoInfoクラス内にそのまま記述しています。
Private Function 日時変換(dateString As String) As String
Dim topString As String
topString = Mid(dateString, 1, 1)
dateString = Replace(dateString, topString, "", 1, , vbBinaryCompare)
日時変換 = Mid(dateString, 1, 10)
End Function
特殊コードを含んでいたため、除外する処置をしています。また、時間情報も含んでいますが、ここでは、年月日のみを取得するように切り取っています。
取得した撮影日を元に年フォルダと月フォルダを作成し、画像や動画ファイルを自動で整理するマクロを別記事ファイルを年月別のフォルダに振り分けを行うマクロに記載しています。下記は、一旦、撮影日の取得までのものです。
ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行ってください。
マクロの有効化手順については、こちらも参考にしてください。