[[20191218143920]] 『スマホのファイルを編集したい』(skyblue) ページの最後に飛ぶ

[ 初めての方へ | 一覧(最新更新順) | 全文検索 | 過去ログ ]

 

『スマホのファイルを編集したい』(skyblue)

 いつもお世話になっています。
PCとスマホをケーブルで繋ぎ写真のパスを確認すると

PC\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\〇△.jpg

の様になっています。
このパスではエラーとなり読めません。
何か良い方法が有れば教えて下さい。

< 使用 Excel:Excel2016、使用 OS:Windows10 >


どういうコードで読もうとしているのかと、Android機が手元に無いので確認できませんが、「Pixel 4 XL」の部分にスペース文字があるので、フルパス全体をダブルクォートで括ると、読めませんかね?
(???) 2019/12/18(水) 14:51

>スマホのファイルを編集したい
ここはExcel専用掲示板です。他のサイトで質問するように。

名無し

() 2019/12/18(水) 15:33


 確認されたパスにドライブレターがついてないので、
 マスストレージモードになってなくて、
 MTP(メディア転送プロトコル)で接続されているのだと思います。

 自分の環境では試せないので、申し訳ないですが、

 Set shellOjb =Wscript.CreateObject("Shell.Application")
 Set folObj=shellOjb.NameSpace("PC\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\")

 とかすると、なんか出来るかもしれません。 
(´・ω・`) 2019/12/18(水) 15:39

???さん、´・ω・`さん 貴重なご指導・ご提案を有難うございます。

 二つの案を確認するには少し時間がかかりそうなので、取り急ぎお礼申し上げます。
(skyblue) 2019/12/18(水) 16:35


 ご提案頂いた順番から

●???さん

  下記のようにフルパス全体をダブルクォートで括って試しエラーは出なくなりましたがファイルが見つかりません。
下記でb はブランクになります。

    pth = "pc\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\IMG_20191130_173936.jpg"
    b = Dir(pth)

●・ω・`さん

  Dim shellOjb As Object
  Set shellOjb =Wscript.CreateObject("Shell.Application")

2行目でオブジェクトが必要と出るのは参照設定が足りないのでしょうか?

  十分な知識が無く、お手数をおかけします。
ご指導のほど、よろしくお願いします。

(skyblue) 2019/12/18(水) 17:49


 こめんなさい 
 Set shellOjb =CreateObject("Shell.Application")
 でいいです

 でも、テストしてないので、保証はありません
(´・ω・`) 2019/12/18(水) 17:52

「pc」ではなく、「\\pc」にするとどうでしょうか?(ネットワークドライブのフルパスと同じ書き方)
(???) 2019/12/18(水) 17:54

???さん、´・ω・`さん 急用で外出します。

帰り次第確かめます。
(skyblue) 2019/12/18(水) 19:08


 帰宅しました。
 やってみました。
 NameSpace ダメでした

 Set shellOjb = CreateObject("Shell.Application")
 Set objFolder = shellOjb.BrowseForFolder(0, "フォルダの指定", 0, 17)

 としてフォルダを指定すると、スマホ内部のフォルダが取れるので、
 なんか方法があるのではないかと思いますが...
(´・ω・`) 2019/12/18(水) 20:39

 昨日夜、報告を入れましたが、今朝見ると消えていまして、再度報告します。
記入に時間がかかったせいかな。

●???さん

  「\\pc」もpcを外した「\\Pixel 4」も「ファイル名または番号が不正です」とエラーメッセイジが出ました。

●・ω・`さん

 昨夜に続き、再度確かめました。
「フォルダーの参照」というタイトルで窓が現れ、
「PC\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\」がタイトルの下に示され、
PC以下のフォルダーが並んだ表示が出て、「新しいフォルダーの作成」、「OK」、「キャンセル」が求められています。

 引き続き、ご指導をよろしくお願いします。

(skyblue) 2019/12/19(木) 10:11


調べてみたところ、スマホのフォルダ公開は、Samba経由では無いのですね。 試した事が無かったので、知りませんでした。
とりあえず、DCIM下にあるフォルダを丸ごとPCにコピーする例なぞ書いておきます。iPhoneだとこれでいけたけど、1ファイル指定はできなかったので、ファイル名だけ知りたい!、とかだと、もっと調べてみないと判らないです。(CopyHereする際に、ファイル名を調べればいけそうな気がします…)
 Sub test1()
    Const DstPath = "c:\tmp"
    Dim cPath As Variant
    Dim Org As Object
    Dim Dst As Object
    Dim File As Variant

    With CreateObject("Shell.Application")
        Set cPath = .BrowseForFolder(0, "スマホのDCIMフォルダを選択してください。", 0, "")
        If cPath Is Nothing Then Exit Sub

        Set Org = .Namespace(cPath)
        Set Dst = .Namespace(DstPath)
    End With

    For Each File In Org.Items
        Dst.CopyHere File
    Next File
 End Sub

どんなフォルダ名なのかは、途中で止めて、cPath.Self.Path を表示してみてください。 直接編集できないように思うので、ファイルをPC側にコピーし、編集し、書き戻す、とかしないと駄目かもです。
(???) 2019/12/19(木) 10:16


少し書き換えて、ファイル一覧をシートに表示する例なぞ。
 Sub test2()
    Dim cPath As Variant
    Dim Folder As Variant
    Dim File As Variant
    Dim iR As Long

    With CreateObject("Shell.Application")
        Set cPath = .BrowseForFolder(0, "スマホのDCIMフォルダを選択してください。", 0, "")
        If cPath Is Nothing Then Exit Sub

        For Each Folder In .Namespace(cPath).Items
            For Each File In .Namespace(Folder).Items
                iR = iR + 1
                Cells(iR, "A").Value = Folder.Name
                Cells(iR, "B").Value = File.Name
            Next File
        Next Folder
    End With
 End Sub
(???) 2019/12/19(木) 10:41

●´・ω・`さん

 ???さんのtestを実行して、書かれていた意味が少しわかりました。
手動でフォルダーを選択しろということですか。

●???さん

 二つのテストを実施ました。フォルダーはCameraを選択。

1.最初の test:Dst.CopyHere File のところで
「オブジェクト変数またはWithブロック変数が設定されていません」というエラーメッセイジが出ました。

2.次のtestでは For Each File In .Namespace(Folder).Items のところで
「クラスはオートメーションまたは予測したインターフェイスをサポートしていません」というエラーメッセイジが出ました。

(skyblue) 2019/12/19(木) 11:04


 >手動でフォルダーを選択しろということですか。
 最初のテストとしては、そうです。

 昨晩、パスに相当する文字列を与えると、自動的にフォルダを掘ってくれるような
 Functionを書こうしましたが、うまくいきませんでした。

 昼間はテスト出来る環境がない(USBデバイスが使えない)ので、
 すみませんが回答できません。
(´・ω・`) 2019/12/19(木) 11:11

Androidだと、Cameraフォルダが指定できるのですね。 iPhoneだと、DCIMより下のフォルダやファイルは、選択すると、使用できない…、的なエラーが表示されてしまい、選択できないのですよ。

とりあえず、サブフォルダがある前提のコードなので、Camera ではなく DCIM フォルダを選択してみてください。 それで動くようなら、Cameraフォルダを指定した場合用に変更する余地があります。
(???) 2019/12/19(木) 11:21


私の書いたコード名testだけでは、会話するのに不便でしたので、test1とtest2に変えておきました。
(???) 2019/12/19(木) 11:23

次は、いちいちフォルダ選択しなくても良いようにして、特定ファイルだけ抜き出してコピーする例です。
 Sub test3()
    Const OrgPath = "PC\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\IMG_20191130_173936.jpg"
    Const DstPath = "c:\tmp"
    Dim Folder As Variant
    Dim File As Variant
    Dim vw As Variant
    Dim i As Long

    vw = Split(OrgPath, "\")

    With CreateObject("Shell.Application")
        Set Folder = .Namespace("")

        For i = 1 To UBound(vw)
            For Each File In Folder.Items
                If File.Name = vw(i) Then
                    If LCase(Right(vw(i), 4)) = ".jpg" Then
                        .Namespace(DstPath).CopyHere File
                    Else
                        Set Folder = .Namespace(File)
                    End If
                    Exit For
                End If
            Next File
        Next i
    End With
 End Sub
(???) 2019/12/19(木) 12:21

●???さん

  大変お世話になっています。test3を試しました。
ソフトは理解できていませんが(余裕がある時に勉強します)、Fileはスマホ内のフォルダーやファイルを拾っています。

Fileが「IMG_20191130_173936.jpg」になったところで「 .Namespace(DstPath).CopyHere File」で止まり、実行時エラー91「オブジェクト変数またはWithブロック変数が設定されていません」というエラーメッセイジが出ました。
(skyblue) 2019/12/19(木) 14:26


●???さん

 大変お世話になっています。

Set Folder = .Namespace(File)の.Namespace(File)は以下のように変化しました。

Pixel 4 XL
内部共有ストレージ
DCIM
Camera
(skyblue) 2019/12/19(木) 14:38


ふむふむ、フォルダ階層を降りていくのは成功したようですね。 予想通り、フォルダ名が違っても、AndroidもiPhoneも、同じ構成なんですね。

出力先フォルダを定数 DstPath で指定してますが、このフォルダを用意していなかった、とかないでしょうか?
(???) 2019/12/19(木) 14:44


●???さん

  "c:\tmp"の事でしょうか?

外出前に読んだところなので、理解できていないこともあり、帰ってからまた用意します。
(skyblue) 2019/12/19(木) 15:11


 >  "c:\tmp"の事でしょうか?
はい、おそらくそこですね。

更に、ファイル名にワイルドカードを使えるようにしても良さそうだなぁ、ということで変えてみたのが以下になります。(フォルダ名のワイルドカード指定には対応していません)

 Sub test4()
    Const OrgPath = "PC\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\IMG_20191130_*.jpg"
    Const DstPath = "c:\tmp"
    Dim Folder As Variant
    Dim File As Variant
    Dim vw As Variant
    Dim i As Long

    vw = Split(OrgPath, "\")

    With CreateObject("Shell.Application")
        Set Folder = .Namespace("")

        For i = 1 To UBound(vw)
            For Each File In Folder.items
                If File.Name Like vw(i) Then
                    If File.IsFolder = False Then
                        .Namespace(DstPath).CopyHere File
                    Else
                        Set Folder = .Namespace(File)
                        Exit For
                    End If
                End If
            Next File
        Next i
    End With
 End Sub
(???) 2019/12/19(木) 15:43

●???さん

 大変お世話になっています。
帰ってきました。

1.c\tmpを作りました

2.UBound(vw)は5でした

3.Fileは下記のものでした
ダウンロード
3D オブジェクト
ピクチャ
ミュージック
デスクトップ
ドキュメント
ビデオ
ローカル ディスク (C:)
BD-RE ドライブ (E:)
ローカル ディスク (G:)
回復 (I:)

4.If File.Name Like vw(i) Then はパスされました。。
 原因究明で、File.Name と vw(i)をトレースしたのが下記で(見辛いですが)この組み合わせは一致していません。

File.Name    vw(i)
ダウンロード Pixel 4 XL
3D オブジェクト Pixel 4 XL
ピクチャ Pixel 4 XL
ミュージック Pixel 4 XL
デスクトップ Pixel 4 XL
ドキュメント Pixel 4 XL
ビデオ Pixel 4 XL
ローカル ディスク (C:) Pixel 4 XL
BD-RE ドライブ (E:) Pixel 4 XL
ローカル ディスク (G:) Pixel 4 XL
回復 (I:) Pixel 4 XL
ダウンロード 内部共有ストレージ
3D オブジェクト 内部共有ストレージ
ピクチャ 内部共有ストレージ
ミュージック 内部共有ストレージ
デスクトップ 内部共有ストレージ
ドキュメント 内部共有ストレージ
ビデオ 内部共有ストレージ
ローカル ディスク (C:) 内部共有ストレージ
BD-RE ドライブ (E:) 内部共有ストレージ
ローカル ディスク (G:) 内部共有ストレージ
回復 (I:) 内部共有ストレージ
ダウンロード DCIM
3D オブジェクト DCIM
ピクチャ DCIM
ミュージック DCIM
デスクトップ DCIM
ドキュメント DCIM
ビデオ DCIM
ローカル ディスク (C:) DCIM
BD-RE ドライブ (E:) DCIM
ローカル ディスク (G:) DCIM
回復 (I:) DCIM
ダウンロード Camera
3D オブジェクト Camera
ピクチャ Camera
ミュージック Camera
デスクトップ Camera
ドキュメント Camera
ビデオ Camera
ローカル ディスク (C:) Camera
BD-RE ドライブ (E:) Camera
ローカル ディスク (G:) Camera
回復 (I:) Camera
ダウンロード IMG_20191130_*.jpg
3D オブジェクト IMG_20191130_*.jpg
ピクチャ IMG_20191130_*.jpg
ミュージック IMG_20191130_*.jpg
デスクトップ IMG_20191130_*.jpg
ドキュメント IMG_20191130_*.jpg
ビデオ IMG_20191130_*.jpg
ローカル ディスク (C:) IMG_20191130_*.jpg
BD-RE ドライブ (E:) IMG_20191130_*.jpg
ローカル ディスク (G:) IMG_20191130_*.jpg
回復 (I:) IMG_20191130_*.jpg

(skyblue) 2019/12/19(木) 17:34


ん〜? 3番の段階で、スマホのフォルダが出てきていませんね? スマホを接続してあるでしょうか?
エクスプローラで、ドライブ表示しているところにスマホ名が表示されている事を確認してみてください。
(???) 2019/12/19(木) 17:54

●???さん

 失礼しました。

ケーブルの先に変換器をつけていて接続が悪かったようでした。

c:\tmpに目的の写真が入っていました。

ソフトの中身を理解しなければなりませんが、応用すると編集もできそうですね。

有難うございました。

分からないところは教えてください。
(skyblue) 2019/12/19(木) 18:48


●???さん

  多変お世話になっています。
まだ何が分からないかが分からない状態ですが、いくつか分からないことがあり質問します。

1.スマホのファイルは直接編集できないため、複雑な方法を採用せざるを得ないということでしょうか?

2.直接編集できないとなると、スマホのファイルはPC側からVBAで消去できないのでしょうか?

3.同じ理由でPCで編集したファイルをVBAでスマホに収納させることもできないのでしょうか?

4.以上について、可能な内容が有れば簡単な具体例を教えてください。

 よろしくお願いします。
(skyblue) 2019/12/19(木) 22:04


スマホのフォルダはWindowsのファイル形式とは違っているので、普通の命令では見る事もできない、ということです。 OSとしては対応しており、エクスプローラでは表示できるので、Shellオブジェクトを使う事でこれに便乗している、という感じですね。

そして、DCIMフォルダ下のファイル編集や削除は、iPhoneでは一切できません。 Androidでどうなるかは、試してみてください。 エクスプローラ上で試せば、可能かどうかは判るでしょう。 可能だったら、削除命令や他のアプリにファイルを開かせる事が可能か試す余地があります。(エクスプローラ上からペイントブラシで開く事はできるので、開く方法はあると思いますが、上書き保存はできませんでした)

コピーしたものならば、Windowsのファイルシステムの配下になるので、編集等は自由にできます。 スマホに書き戻す必要性を感じませんが、iPhoneでもDCIMフォルダ以外ならば書き込みできるので、元のフォルダには駄目でしたが、共有された直下等ならは自由に書き込めると思いますよ。(AndroidはiPhoneより緩いので、DCIMフォルダ下でも書けるかも?)

ヒントは与えたのだし、それ以上の事を実現するのは貴方自身です。 いろいろ試してみてください。
(???) 2019/12/20(金) 09:40


●???さん

 厚かましいお願いでしたが、親切に有難うございました。

自分も知りたかったことですが、読んでいる人がいるかもしれないと予想し、ご迷惑を顧みず突っ込んだ質問をしました。

 大変参考になりました。

仰る通り、今後は自分で試してみます。

スマホをアンドロイドにしたのは、内部のファイル操作ができやすいと聞いていたからでした。
(skyblue) 2019/12/20(金) 11:29


追加情報です。

エクスプローラで、ペイントブラシ等のMS製アプリなら開けましたが、普通のアプリだと開けませんでした。MSはちゃんとスマホのフォルダに対応しているのですね。 この場合、エクスプローラで見ることのできるフルパス指定でいけます。 MS以外のアプリで開くならば、コピーしてから開く必要がありますが、ビューアで良いならコピーせずにいけそう。

また、iPhoneのDCIMフォルダ下ですが、上書きや新規作成、リネーム等はできないのですが、ファイルの削除はできるようです。 変わった権限の付け方をしていますねぇ。
(???) 2019/12/20(金) 13:10


●???さん

 追加の情報有難うございます。
このテーマは他の人が質問しているかもしれないと思い覗いてみました。

 実は、ファイル削除は期待していた重要な機能です。

 目的の一つとして、スマホのファイル容量が限度に達した場合、最も大きい動画などのファイルを選択しPCのHDDに整理して記憶させ、スマホ側のファイルを消去させる作業を実施させたいところです。

 pixelはmicroSDをプラスできないので(iPhoneも同様と聞いています)スイッチ一つで容量問題を解決出来れば助かります。

 今後も貴重な情報が有ればお願いします。
(skyblue) 2019/12/20(金) 14:31


ファイルサイズも得たいならば、以下とかどうでしょうか。
(ファイル名部分は*.*にすると全部羅列します)
 Sub test5()
    Const OrgPath = "PC\Pixel 4 XL\内部共有ストレージ\DCIM\Camera\IMG_20191130_*.jpg"
    Dim Folder As Variant
    Dim File As Variant
    Dim vw As Variant
    Dim i As Long
    Dim j As Long
    Dim iR As Long

    Application.ScreenUpdating = False

    Cells.Clear
    iR = 1
    vw = Split(OrgPath, "\")

    With CreateObject("Shell.Application")
        Set Folder = .Namespace("")
        For i = 1 To UBound(vw)
            For Each File In Folder.Items
                If File.Name Like vw(i) Then
                    If File.IsFolder = False Then
                        If Range("A1") = "" Then
                            For j = 0 To 4
                                Cells(1, j + 1).Value = Folder.GetDetailsOf(0, j)
                            Next j
                        End If
                        iR = iR + 1
                        For j = 0 To 4
                            Cells(iR, j + 1).Value = Folder.GetDetailsOf(Folder.ParseName(File.Name), j)
                        Next j
                    Else
                        Set Folder = .Namespace(File)
                        Exit For
                    End If
                End If
            Next File
        Next i
    End With

    With ActiveSheet.Sort
        .SortFields.Clear
        .SortFields.Add Key:=Range("B2:B" & iR), Order:=xlAscending
        .SortFields.Add Key:=Range("A2:A" & iR), Order:=xlAscending
        .SetRange Range("A1").CurrentRegion
        .Header = xlYes
        .SortMethod = xlPinYin
        .Apply
    End With

    Columns("A:E").AutoFit

    Application.ScreenUpdating = True
 End Sub

エクスプローラだとサイズは1バイト単位で得ているようですが、何故かこの情報だとMBやKBのように丸められた値が単位付きで入ってしまってます。 サイズ順のソートが難しいですね。
あと、「状態」列が更新日時で、「更新日時」が作成日時のような気がするのですが、GetDetailsOfが返すものをそのまま書き出しています。 MSかAppleが間違えているような気がします。

スマホ内整理が目的なら、エクスプローラ上で表示や削除を行うのが、最も早くて有効なように思いますね。 マクロで出来そうなのは、特定日時より前を全部消す、とかくらいですが、それはエクスプローラで日付ソートして範囲削除すればできてしまいますから。
(???) 2019/12/20(金) 18:31


●???さん

 精力的に、大変丁寧にソフトを制作・紹介いただき、お礼申し上げます。

 個人的に時間的余裕が無いことも有りますが、まだわからないことだらけで、自分なりのソフトを作るには時間がかかりそうです。

 従って、実際のソフトを示して頂くのは有難いです。

 シートへの出力が下記のものです(表が入力できないのでずれが生じます)。
状態の中身が空白になっていました。

     名前	            種類      サイズ	状態	      更新日時
IMG_20191130_173936.jpg	JPG ファイル  5.54 MB	2019/11/30 17:39	
(skyblue) 2019/12/20(金) 22:31

Androidだと、日付情報が1つでしたか。 作成日時と更新日時はあると思うので、iPhoneとはIDが違うか、更新情報が無いのかでしょう。(Windowsのフォルダでも、少し違います) そもそも、「状態」という名前のIDに更新日時が返ってくるiPhoneがおかしいのです。

test5で、jのループ2か所を、4ではなく100くらいを指定してみてください。 動作は遅くなりますが、得られるプロパティが全部表示されると思います。 これでも日付情報が1つのようならば、作成されてから一度も更新されていない場合、Androidは更新日時を記録していないと考えて良さそう。 複数の日時が得られた場合は、ファイル名でも作成日時は判るので、これで作成日時なのか更新日時なのか判断できるでしょう。
(???) 2019/12/23(月) 09:20


コメント返信:

[ 一覧(最新更新順) ]


YukiWiki 1.6.7 Copyright (C) 2000,2001 by Hiroshi Yuki. Modified by kazu.