[[20200411115103]] 『ファイルを若番順に読み出す方法を教えて下さい。』(katanohosi) ページの最後に飛ぶ

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

 

『ファイルを若番順に読み出す方法を教えて下さい。』(katanohosi)

 写真フォルダにファイル名を1.jpgから順番に名前をつけて保存しています。
 変数のKsは、写真の数と同じ数値です。
 つまり順番に変数iと同じ数字を指定して、1.jpgをC7、2.jpgをC9・・・・・と貼り付けていくつもりだったのですが、
 写真を都合により削除する場合が出てきました。
 2.jpgを削除したとき、順番が1.jpg 3.jpgとなるため、i=2の時、該当の写真がなくなるため不具合が出ます。
 それで変数iによらず違う方法で、できれば1.jpgのようにリネームせずに
 撮影したときに付与される番号のままで、小さい数字順に読み込める方法を教えて下さい。

            s = 7
            For i = 1 To Ks
                With ActiveSheet.Pictures.Insert(mypath & "\写真\" & i & ".jpg")
                    .Top = Range("C" & s).Top
                    .Left = Range("C" & s).Left
                    .Width = Range("C" & s & ":C" & s).Width
                    .Height = Range("C" & s & ":C" & s).Height
                End With
                s = s + 2
            Next

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


写真の数字をセルに書き込んでおいて
最後にその数字の順番にセルを並べ替えればどうでしょうか。

(マナ) 2020/04/11(土) 12:49


空き番があるだけで、規則的にならんでいるのでしたら、
Dir関数でファイルが存在するかどうかを確認し、
存在するものだけ処理対象としてはどうでしょうか。
(γ) 2020/04/11(土) 13:01

 ありがとうございます。
下記のように、個数の確認をしていますが、存在する物だけ処理対象とする方法はどんなやりかたが有りますでしょうか。
 よろしくお願いします。

Application.ScreenUpdating = False

    tmp = Dir(ppath & "*.jpg") 'Jpg数把握
        Do While tmp <> ""
            cnt = cnt + 1
            tmp = Dir()
        Loop

    ChDir ThisWorkbook.Path
            With CreateObject("Scripting.FileSystemObject").Getfolder(mypath)
                  For Each myFile In .Files
                    If myFile.Name Like "拾得物件一覧簿*.xlsx" Then
                          With Workbooks.Open(fileName:=myFile.Path)
                          strWorkBookName1 = ActiveWorkbook.Name
                          End With
                          Exit For
                    End If
                  Next myFile
            End With
    Kg = Cells(Rows.Count, 1).End(xlUp).Row
    Ks = (Kg - 4) / 2
        If Ks <> cnt Then
           MsgBox "項目数と写真の数が合いません。処理を終了します。"
           ActiveWorkbook.Close
           Exit Sub
        End If

(katanohosi) 2020/04/11(土) 13:04


 つまり、こんな風なことを想像していました。
    s = 7
    For i = 1 To Ks
        f = mypath & "\写真\" & i & ".jpg"
        If Dir(f) <> "" Then
            With ActiveSheet.Pictures.Insert(f)
                .Top = Range("C" & s).Top
                .Left = Range("C" & s).Left
                .Width = Range("C" & s & ":C" & s).Width
                .Height = Range("C" & s & ":C" & s).Height
            End With
            s = s + 2
        End If
    Next

(γ) 2020/04/11(土) 13:06


確かに、そうでした。
わたしのは取り下げます。

(マナ) 2020/04/11(土) 13:12


γさん
ありがとうございます。
やはり2.jpgが無い場合は3.jpgが2番目に貼りつきますが、その他のファイル名14.jpgはiと合致しないため
貼りつきません。
何か良い方法があればよろしくお願いします。
(katanohosi) 2020/04/11(土) 13:25

えーと、何がまずいのかわかりません。

2.jpgはどうなればいいんですかね。

そして
その他のファイル名14.jpgはiと合致しない
と、突然、その他のファイルと言われても。
Ks が14 より小さいからではないんですか?

もう一段、説明ください。

(γ) 2020/04/11(土) 13:37


 (γ)さん
 意味不明の書き込み、失礼しました;
 言われるとおり14.jpgは関係ない物です。

 最初に写真フォルダ内には、1.jpg〜13.jpgが有り、貼り付け先の表にも2行ずつを結合させた行が13行あります。
 なので各行(A列)の項番は1〜13です。その右列(B列)に個別の整理番号が記載され、C列は行の結合はされて無く、上の行に品名、下の行に写真を貼り付けるようにしています。
 表題と見出し行が5行目まであります。
 Kg = Cells(Rows.Count, 1).End(xlUp).Row
 Ks = (Kg - 4) / 2
 これで項目数をカウントさせています。ここでKsは13です。13項目ありますので写真も13あります。

 今回、8項目の品物が削除になったので写真8.jpgも削除しました。
ですのでKsは12になります。項目数は1〜12で存在しますが、写真は1.jpg〜7.jpgと9.jpg〜13.jpgです。
  個数は12個なので項目数と写真の数は合致します。
これでマクロを実行させると 「picturesクラスのInsertプロパティを取得で きません。」とエラーが出ます。
写真も7.jpgまで貼りついて止まります。
 対策としては9.jpg以降の写真の名前を8.jpgへとリネームすれば片付くのですが、たくさんあった場合が時間がかかるので、変数iと絡まない方法で順番に貼り付けられないかを探しています。

 よろしくお願い致します。

(katanohosi) 2020/04/11(土) 14:40


Ksを決める論理が不明です。
私はjpgファイルについている数字の最大値を
Ksにするのが自然としか思えません。
これで失礼します。

(γ) 2020/04/11(土) 14:51


 (γ)さん
 お手数お掛けしました。
 ありがとうございました。
(katanohosi) 2020/04/11(土) 14:58

 お騒がせ致しました。
 ググって探し回り、無事解決致しました。
 ありがとうございました。
 よく分かってはいないのですが、下記でファイル名若番号順で貼りつくようになりました。
                s = 7
                tmp = Dir(ppath & "*.jpg")
                       Do While tmp <> ""
                            With ActiveSheet.Pictures.Insert(ppath & tmp)
                                .Top = Range("C" & s).Top
                                .Left = Range("C" & s).Left
                                .Width = Range("C" & s & ":C" & s).Width
                                .Height = Range("C" & s & ":C" & s).Height
                            End With
                            s = s + 2
                           cnt = cnt + 1
                           tmp = Dir()
                       Loop

(katanohosi) 2020/04/11(土) 16:51


 解決されたとのことですが、本当ですか?心配です。
 閲覧者が誤解されてはいけないのでコメントしておきます。

 「Dir関数のファイルを取り出す順番について」
https://qiita.com/BlackCat777/items/29fbfcbb4ec291b55d63 
 では、
 マイクロソフトの公式見解として、以下が引用されています。
 | Dir関数(Visual Basic for Application)|Microsoft Docs
 | ファイル名は特定の順序で取得されるわけではないため、
 | 必要に応じて、返されたファイル名を配列に格納し、その配列を並べ替えます。

 例えば、実際に試してみると、
 1.jpg  2.jpg 11.jpg の3つがあるフォルダで順次 Dir関数で取り出すと、
 一見すると順番のようですが、
 1.jpg  
 11.jpg
 2.jpg 
 となって、あなたの希望に沿っていないと思います。
 (もっとも、これは01.jpgといった番号の付け方をすれば避けられる、
   と言えるかもしれませんが。ただ、マイクロソフトはこれも保証できないと言っている。)

 やはり、私が示したように、 For .. Next で順次、ファイル名候補を挙げ、
 そのうち実際に存在するものについてだけ、その順序で処理する方式が確実だと思います。
(γ) 2020/04/12(日) 08:49

 (γ)さん ご親切にありがとうございます。
 言われるとおり、確かに読み出しが1.jpg,11.jpgと意図しない順番で読み込まれました。
 1.jpgのファイル名は、手修正しました。
 今のところ、カメラで撮影したファイル名は4桁の数字ですので、当面は大丈夫だと思います。
でもこの問題に出会うときは来ると思いますが、そのときは手間ではありますが「もっとも、これは01.jpgといった番号の付け方をすれば避けられる、
 と言えるかもしれませんが。」などの対応をしてみます。

 最後までご心配いただき、ご教授ありがとうございました。
(katanohosi) 2020/04/12(日) 12:59

コメント返信:

[ 一覧(最新更新順) ]


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