ファビコン。井の家紋。画像ファイルや動画ファイルの撮影日を取得するマクロ | エクセルマクロ(VBA)実践蔵(じっせんぐら)

前の項目 - 複数シートを別ブックへ移動して保存するマクロ
次の項目 - ファイルを年月別のフォルダに振り分けを行うマクロ

画像ファイルや動画ファイルの撮影日を取得するマクロ最終更新日:2023-06-02

このページは、画像や動画ファイルのプロパティ詳細(拡張情報)から作成日を取得するマクロの解説とエクセルマクロ有効ブックのダウンロードが可能です。

このページの目次

はじめに - 概要説明

画像ファイルや動画ファイルの整理をしたいと思い、撮影日やメディアの作成日を取得するマクロを作りました。

windowsのエクスプローラ画面上で、動画ファイルや画像ファイルを右クリックして「プロパティ」を表示させ、「詳細」タブに表示させる撮影日やメディアの作成日を取得するものです。

画像ファイルは、撮影日に日付が設定されており、動画ファイルは、「メディアの作成日」という項目に情報が入ります。

動作確認している環境は、Windows11になります。

画像ファイルのプロパティ詳細タブ情報External information(Exif)動画ファイルのプロパティ詳細タブ情報External information(Exif)

マクロ実行後の結果画面

結果画面のサンプル

フォルダ参照とファイル名一覧の取得については、別途、記載済みなので、下記の関連記事を参照してください。

ファイル名一覧のパスを元に、撮影日を取得する

上図の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クラスオブジェクトの内容を記述します。

自作のPhotoInfoクラス

クラスを作成するには、Visual Basic画面のプロジェクトエクスプローラ画面にて右クリックしてクラスを追加してください。

Visual Basic画面のメニュー「表示」->「プロパティウィンドウ」を表示させ、オブジェクト名を「PhotoInfo」に変更する。

下記のコードを動作させるためには、参照設定に「Microsoft Shell Controls And Automation」と「Microsoft Scripting Runtime」の追加が必要です。

参照設定の設定方法は、こちら。

PhotoInfoクラスの初期化処理

まずは、クラスの初期化処理で、「撮影日時」の格納位置を取得します。

 
'参照設定 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

PhotoInfoクラスの初期化処理の解説

画像や動画ファイルを格納しているフォルダパスを引数で受け取る。

「撮影日時」と「メディアの作成日」という名前と一致する位置情報を保存する。

クラス型の場合は、関数外に変数を宣言することができます。(クラス内のグローバル変数)特別な変数のため、変数名を日本語にしています。

PhotoInfoクラスの撮影日時取得処理

下記は初期化クラスの下につづけて記述します。

 
'日付を取得
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

PhotoInfoクラスの撮影日時取得処理の解説

引数でファイルパスを受け取り、初期化処理で取得した、「撮影日位置」や「メディアの作成日」位置情報を元にファイル個別の情報を取得し、戻り値として返します。

GetDetailsOfメソッドで取得できる日付をVBAで日時として処理できるように成型する処理を日時変換に切り出しています。

PhotoInfoクラスの日時変換処理

下記に日時変換()関数を記載します。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

PhotoInfoクラスの日時変換処理の解説

特殊コードを含んでいたため、除外する処置をしています。また、時間情報も含んでいますが、ここでは、年月日のみを取得するように切り取っています。

エクセルマクロ有効ブックのダウンロード

取得した撮影日を元に年フォルダと月フォルダを作成し、画像や動画ファイルを自動で整理するマクロを別記事ファイルを年月別のフォルダに振り分けを行うマクロに記載しています。下記は、一旦、撮影日の取得までのものです。

ダウンロードしたエクセルファイルを起動し、コンテンツの有効化を行ってください。

マクロの有効化手順については、こちらも参考にしてください。

画像や動画ファイルの撮影日を取得するエクセルマクロ有効ブック(xlsm)のダウンロード

前の項目 - 複数シートを別ブックへ移動して保存するマクロ
次の項目 - ファイルを年月別のフォルダに振り分けを行うマクロ