Sub test()
Dim objFS, objFol, shellObj, folderObj, myFol, myFile
Dim i As Long
Dim myName As String
myFol = "C:\Users\test"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFol = objFS.GetFolder(myFol)
Set shellObj = CreateObject("Shell.Application")
Set folderObj = shellObj.Namespace(myFol)
Cells(1, 1) = "ファイル名"
Cells(1, 2) = "撮影日時"
For Each myFile In objFol.Files
myName = myFile.Name
If UCase(Right(myName, 3)) = "JPG" Then
i = i + 1
Cells(i, 1) = myName
Cells(i, 2) = folderObj.GetDetailsOf(folderObj.ParseName(myName), 12)
End If
Next
Set objFS = Nothing
Set objFol = Nothing
Set shellObj = Nothing
Set folderObj = Nothing
End Sub
このコードをエクセルシート上に書き出せば、問題なく日付が書き出せるのに、
Debug.Print folderObj.GetDetailsOf(folderObj.ParseName(myName), 12)
とすると、
撮影日時が
?2010/?02/?28 ??14:04
?2010/?05/?15 ??15:14
?2010/?05/?23 ??16:45
?2010/?06/?03 ??18:19
?2010/?06/?19 ??13:25
?2010/?06/?26 ??10:22
?2010/?06/?29 ??18:39
?2010/?07/?01 ??18:23
?2010/?07/?02 ??19:13
のようにハテナが入るのですが、なぜでしょうか?
追記。
OSによっては、撮影日のカラム名が「写真の撮影日」だったり「撮影日時」だったりします。
例えば、XPでは「写真の撮影日」ですが、Windows7では「撮影日時」になります。
OSが違っても動くように
For i = 0 To 99999
If folderObj.GetDetailsOf(Nothing, i) = "写真の撮影日" Then Itemnumber = i
Next
の部分を
For i = 0 To 99999
' XP対応
If folderObj.GetDetailsOf(Nothing, i) = "写真の撮影日" Then Itemnumber = i
' Win7対応
If folderObj.GetDetailsOf(Nothing, i) = "撮影日時" Then Itemnumber = i
Next
のように、何種類も書いておくと良いでしょう。
調べてはいませんが、VistaはVistaで、撮影日のカラム名が違うかも知れません。違う場合は、上記のようにif文を足しましょう。
>のようにハテナが入るのですが、なぜでしょうか?
GetDetailsOfが返す値は、OSに依存します。
特に、日付などは、コントロールパネルの地域と言語のオプションの「形式」設定の「短い日付形式」で指定されている形式で返されます。
その際、返されるのは「文字列」で、その文字列の内容は、Unicode文字など「OSに依存した文字コード」になります。
返された文字列の中に、エクセルでサポートされていないUnicode文字などがあれば、代替文字として「?」が表示されます。
>エクセルシート上に書き出せば、問題なく日付が書き出せるのに
「セルに日付が入る」のは、実は「偶然」なのですよ。
返された文字列が「中に表示不可能なUnicode文字があったけど、偶然、日付と解釈できる文字列だった為」に、セルに代入される際に「日付シリアル値」に変換されて代入されたのです。
もし、コントロールパネルの地域と言語のオプションの「形式」設定で、日付の形式を「yyyy/MM/dd'('ddd')'」などと設定してあると「2014/07/04(金)」のような文字列が返って来てしまい、エクセルが日付シリアル値に変換できない為、セルに代入されるのは「文字列のまま」になります。
「どのような文字列が返って来るか?」は「実行環境により異なる」ので注意して下さい。
また、GetDetailsOfの2つ目の引数の「iColumn引数」は、実行するフォルダによって異なります。
貴方の環境では「偶然12だっただけ」で、他の環境では動きません。
環境に依存しないようにするには、以下のようにしないといけません。
Sub test()
Dim objFS, objFol, shellObj, folderObj, myFol, myFile
Dim i As Long, ColumnNumber As Long
Dim myName As String
myFol = "C:\Users\test\"
Set objFS = CreateObject("Scripting.FileSystemObject")
Set objFol = objFS.GetFolder(myFol)
Set shellObj = CreateObject("Shell.Application")
Set folderObj = shellObj.Namespace(myFol)
' とりあえず0(名前)を取得する値で初期化
ColumnNumber = 0
' 撮影日のカラム番号を探す
For i = 0 To 99999 '←充分に大きい値
' GetDetailsOfの1番目の引数にNothingを指定して0から順にカラム名を取得
If folderObj.GetDetailsOf(Nothing, i) = "写真の撮影日" Then ColumnNumber = i
Next
'iを使ったので初期化しておく
i = 1
Cells(1, 1) = "名前"
Cells(1, 2) = "撮影日"
For Each myFile In objFol.Files
myName = myFile.Name
If UCase(Right(myName, 3)) = "JPG" Then
i = i + 1
Cells(i, 1) = myName
' ここで返される文字列は「エクセルが日付として認識できない文字列になっている可能性がある」事に注意。
Cells(i, 2) = folderObj.GetDetailsOf(folderObj.ParseName(myName), ColumnNumber)
End If
Next
Set objFS = Nothing
Set objFol = Nothing
Set shellObj = Nothing
Set folderObj = Nothing
End Sub
>このコードをエクセルシート上に書き出せば、問題なく日付が書き出せるのに、
撮影日時の入っていいるセルをコピーして
イミディエイトウィンドウにペーストするか
イミディエイトウィンドウ上で、?cells(2,2) として確認すると
ハテナ付の ?2010/?02/?28 ??14:04 などのままではありませんか?
GetDetailsOf でVBAでは表示できないコードが ? で代わりに表示されるようです。
なので、
前略
dim sTime as string,NsTime as string ’追加
i = i + 1
Cells(i, 1) = myName
sTime =folderObj.GetDetailsOf(folderObj.ParseName(myName), 12)
For i = 1 To Len(sTime) 'ごみ取りのループ
If Mid(sTime, i, 1) Like "[0-9,/ :]" Then
NsTime = NsTime & Mid(sTime, i, 1)
End If
Next
Cells(i, 2) = cdate(NsTime)
End If
のような感じでごみ取りしてからにしています。
蛇足ですが、GetDetailsOf では秒の単位は取得できないので
http://okwave.jp/qa/q8652257.html
もご参考に。
(emsuja さん、mitarashi さんの受け売りですけど・・・)
お礼
回答頂きありがとうございました。