mougにあった質問関連のメモです。
ポータブル デバイスからファイルをコピーする手段として、「Copy/Move Files from Portable Device」ではShellオブジェクトが使われていました。
※ Copy/Move Files from Portable DeviceのコードをVBA向けに直したものが下記になります。
Option Explicit Public Sub GetFolderPath() Dim fol As Object With CreateObject("Shell.Application") Set fol = .BrowseForFolder(0, "ポータブル デバイス上のフォルダーを選択してください。", 0, "") If fol Is Nothing Then Exit Sub Debug.Print fol.Self.Path End With End Sub Public Sub CopyItems() Dim srcFol As Object, dstFol As Object Dim itm As Object Const srcFolPath As String = "::{20D04FE0-…" 'GetFolderPathプロシージャーで取得したポータブル デバイス上のフォルダーのパス Const dstFolPath As String = "C:\Test" 'コピー先フォルダーのパス With CreateObject("Shell.Application") Set srcFol = .Namespace(srcFolPath) Set dstFol = .Namespace(dstFolPath) For Each itm In srcFol.Items dstFol.CopyHere itm Next End With Debug.Print "処理が終了しました。" End Sub
BrowseForFolderでポータブル デバイス上のフォルダーのパスを取得して、CopyHereでファイルのコピーを行う形ですが、いちいちフォルダーを選択するのは面倒なので、フォルダーを選択する部分を端折った処理を考えてみました。
Option Explicit Public Sub Sample() CopyPDItems "コンピューター\(機種名)\SDカード\DCIM\100MEDIA", "C:\Test" MsgBox "処理が終了しました。", vbInformation + vbSystemModal End Sub Private Sub CopyPDItems(ByVal SrcFolderPath As String, ByVal DstFolderPath As Variant) 'ポータブル デバイスにあるフォルダーの中身を指定したフォルダーにコピーする ' - SrcFolderPath:コピー元フォルダーのパス(ポータブル デバイス) ' - DstFolderPath:コピー先フォルダーのパス Dim PDFolderPath As Variant Dim ParentFolderPath As Variant Dim SrcFolder As Object, DstFolder As Object Dim itm As Object Dim v As Variant Dim i As Long, num As Long PDFolderPath = "": ParentFolderPath = "" '初期化 If Right(SrcFolderPath, 1) = ChrW(&H5C) Then SrcFolderPath = Left(SrcFolderPath, Len(SrcFolderPath) - 1) '右端のパスセパレーター除去 v = Split(SrcFolderPath, ChrW(&H5C)) If v(0) = "コンピューター" Then 'パス最初の「コンピューター」は無視する num = 1 Else num = LBound(v) End If For i = num To UBound(v) PDFolderPath = GetPDFolderPath(ParentFolderPath, v(i)) If Len(PDFolderPath) < 1 Then MsgBox "フォルダーが見つかりません。" & vbCrLf & "処理を中止します。", vbCritical + vbSystemModal Exit Sub End If ParentFolderPath = PDFolderPath Next With CreateObject("Shell.Application") Set SrcFolder = .Namespace(PDFolderPath) Set DstFolder = .Namespace(DstFolderPath) If SrcFolder Is Nothing Or DstFolder Is Nothing Then MsgBox "フォルダーが見つかりません。" & vbCrLf & "処理を中止します。", vbCritical + vbSystemModal Exit Sub End If On Error Resume Next For Each itm In SrcFolder.Items DstFolder.CopyHere itm 'フォルダー含めてコピー Next If Err.Number <> 0 Then MsgBox "エラーが発生しました。" & vbCrLf & vbCrLf & "エラー番号:" & Err.Number & vbCrLf & "エラー内容:" & Err.Description, vbCritical + vbSystemModal On Error GoTo 0 End With End Sub Private Function GetPDFolderPath(ByVal ParentFolderPath As Variant, ByVal FolderName As String) As String Dim ret As String Dim fol As Object Dim itm As Object ret = "": Set fol = Nothing '初期化 With CreateObject("Shell.Application") Set fol = .Namespace(ParentFolderPath) If Not fol Is Nothing Then For Each itm In fol.Items If itm.Name = FolderName Then ret = itm.Path Exit For End If Next End If End With GetPDFolderPath = ret End Function
上記コードでは「コンピューター\(機種名)\SDカード\DCIM\100MEDIA」のような形でポータブル デバイス上のフォルダーのパスを指定しています。
エラーの処理等大雑把に書いてありますが、一応手元のスマートフォンで動作確認できました。
このコードを参考にデジカメデータをコピーしていましたが,Windows10 1703 Cretors update に上げてから,Namespaceの部分が動かくなくなりました。
Shell32.dllが,2017/6/20のタイムスタンプになっており,差し変わったことが原因と推測します。
色々トライしましたが,回避策がなくて困っています。
> bagino さん
当ブログ管理人です。
Windows 10 Pro Insider Preview バージョン:10.0.16237 ビルド 16237で動作確認したところ、たしかに動作しなくなっておりました。
一部処理を書き換えたコードを記事にしましたので↓、こちらをご参照ください。
https://www.ka-net.org/blog/?p=8670