[[20160622122054]] 『【マクロ】ファイル移動』(ひでちゃん) ページの最後に飛ぶ

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

 

『【マクロ】ファイル移動』(ひでちゃん)

C:\TEST\フォルダ1

 *【YYYYMMDD】*****.xlsx
 **【YYYYMMDD】*****.xlsx
【YYYYMMDD】*****.xlsx
C:\TEST\フォルダ2
 *【YYYYMMDD】*****.xlsx
 **【YYYYMMDD】*****.xlsx
【YYYYMMDD】*****.xlsx
C:\TEST\フォルダ3
 *【YYYYMMDD】*****.xlsx
 **【YYYYMMDD】*****.xlsx
 【YYYYMMDD】*****.xlsx

上記の様にフォルダがいくつも存在し、
各フォルダに格納されているファイルを
”C:\TEST\過去”フォルダに移動をしたい
(削除対象はyyyymmddがtoday()-1以前のものを削除)
のですが、マクロでできますでしょうか。

マクロ初心者の為、どのように記述したらよいのか分からず、
教えていただきたく宜しくお願いいたします。

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


1日前は残すという条件等、質問内容が [[20160615135114]] とそっくりなのですが、同じ方でしょうか?
同じならば、ニックネームはころころ変えないようにしてください。別人ならば、同じ事を最初から書かなければならなくなったりしますし、貴方の力量が判らないので、適切な回答にならないかも知れませんから。

質問内容で、不確定なところを尋ねます。

 > C:\TEST\フォルダ2
 >  *【YYYYMMDD】*****.xlsx
 >  **【YYYYMMDD】*****.xlsx

ファイル名先頭の*は、何の意味があるのでしょうか? 前回(今回が初なのかも知れませんが、その場合は似た前例ということで)では、【20160614】【あ】xxxxxxx.xlsx のように、括弧始まりでした。また、同じ括弧が二重になっているので、これを考慮したコーディングにする必要がありました。今回は、括弧で始まらない場合もある、括弧の重複はない、という事でしょうか?

また、移動先は C:\TEST\過去 との事ですが、その下に「フォルダ1」等のサブフォルダは存在しますか? それとも、フォルダ作成も行うコーディングにする必要があるのでしょうか?

フォルダ作成が必要な場合、その階層は必ず1段階でしょうか? それとも、2段階や3段階等、例よりも深い場合がありますか?

フォルダ作成は MkDirステートメント、ファイル移動は Nameステートメントです。サブフォルダを含めた複数ファイルを扱うコーディングは、前回の例があります。さて、貴方はこれらのヒントを得て、まずご自分で作ってみよう、という気持ちはありますか? それとも、試しもせずに諦めて、丸投げしますか?

ちなみに、初心者だから判らない、という主張は、しない方が良いでしょう。初心者だからこそいっぱい調べて、いっぱい時間をかけて試してみるものです。 判らない、ではなく、判ろうとしない、というところが、逆に悪い印象を与えてしまいますよ。
(???) 2016/06/22(水) 13:40


???さん

過去の掲示板を見ていなくてすみません。
[20160615135114]をいじってみたのですが、

cFiles = Split(CreateObject("WScript.Shell").Exec("CMD /C DIR /A:-D/B/S """ & cPATH & "【????????】*.xls*""").StdOut().ReadAll(), vbNewLine)

↑この内容が理解できないので教えていただけますでしょうか。

 Sub test()
    Const cPATH = "C:\test\"
    Dim cFiles As Variant
    Dim cw1 As String
    Dim cw2 As String
    Dim i As Long
    cw1 = Format(Now - 1, "YYYYMMDD")
    cFiles = Split(CreateObject("WScript.Shell").Exec("CMD /C DIR /A:-D/B/S """ & cPATH & "【????????】*.xls*""").StdOut().ReadAll(), vbNewLine)
    For i = 0 To UBound(cFiles) - 1
        cw2 = Mid(cFiles(i), InStrRev(cFiles(i), "\【") + 2, 8)
        If cw2 < cw1 Then
            fso.MoveFile "C:test\過去"
        End If
    Next i
 End Sub

↑上記のように書き換えてみたのですが、fso.MoveFile "C:test\過去"でデバックしてしまいます。

ご教示いただきたくお願いいたします。
(ひでちゃん) 2016/06/22(水) 15:11


cFiles に値をセットしている一文は、思いっきり難しい内容なので、考え方だけ書きますね。

VBA標準のDir関数では、指定したフォルダ階層の情報しか得られません。なので、指定したフォルダの下にある階層のフォルダまで見たい場合は、再帰呼び出しのテクニックを使った関数を使うか、2階層に決め打ちしたコーディングにするか、ロジックの工夫をするのが一般的です。

しかし、DOSプロンプト(コマンドプロンプト)の基本命令であるDIRコマンドは、サブフォルダ以下の多階層でも一気に一覧する機能や、フルパスで表示する機能があるので、ExcelからOS命令のDIRコマンドを呼び出し、指定フォルダ以下の一覧を作成しているのが、cFiles の1行になります。

まぁ、フォルダとワイルドカードを指定すると、結果がフルパスで cFiles に配列として格納される、と考えてください。

次に、エラーの原因を指摘します。fso.MoveFile とは、FileSystemObject という、Excelのものではないオブジェクトを利用した方法です。fsoという変数に対するオブジェクト宣言が必要。この命令を見つけたページに、そのあたりも書いてあったはずなので、見直してみてください。

また、MoveFile には引数が2つ必要です。今回は、1つしか指定していませんよね。これではエラーになりますよ。
(???) 2016/06/22(水) 15:47


 Sub test()

    Dim strsrc As String
    Dim strdst As String
    Dim cFiles As Variant
    Dim cw1 As String
    Dim cw2 As String
    Dim i As Long

    strsrc = "C:\test\"
    strdst = "C:\test\過去"
    cw1 = Format(Now - 1, "YYYYMMDD")
    cFiles = Split(CreateObject("WScript.Shell").Exec("CMD /C DIR /A:-D/B/S """ & cPATH & "【????????】*.xls*""").StdOut().ReadAll(), vbNewLine)
    For i = 0 To UBound(cFiles) - 1
        cw2 = Mid(cFiles(i), InStrRev(cFiles(i), "\【") + 2, 8)
        If cw2 < cw1 Then
            fso.MoveFile strsrc, strdst
        End If
    Next i

 End Sub

これで書き換えてみたのですが、移動されませんでした。
どうしてなのでしょうか。
書き換えてみたのですが、
(ひでちゃん) 2016/06/22(水) 16:15


fsoの宣言部分がありませんが、これまだエラーになりませんか? これじゃ動きませんよ。
更に、定数cPATH を消してしまいましたが、DIRの引数に使ってますよね。これも直すこと。

あと、元フォルダと先フォルダを MoveFile の引数にしていますが、元ファイルと先フォルダを指定してください。
(元ファイルは、cFiles(i) ですよね)

思ったように動かない場合は、ステップ実行し、変数の中身を確認し、原因を考えてみてください。
(???) 2016/06/22(水) 16:36


何度もすみません。

 Sub test()

    Const cPATH = "C:\test\"
    Dim cFiles As Variant
    Dim cw1 As String
    Dim cw2 As String
    Dim i As Long
    cw1 = Format(Now - 1, "YYYYMMDD")
    cFiles = Split(CreateObject("WScript.Shell").Exec("CMD /C DIR /A:-D/B/S """ & cPATH & "【????????】*.xls*""").StdOut().ReadAll(), vbNewLine)
    For i = 0 To UBound(cFiles) - 1
        cw2 = Mid(cFiles(i), InStrRev(cFiles(i), "\【") + 2, 8)
        If cw2 < cw1 Then
            fso.MoveFile cFiles(i), "C:test\過去\"
        End If

    Next i

 End Sub

これで変更してみたのですが、movefaileのところでデバックしてしまいます。

調べましたが、原因が全く分かりません。

ご教示いただけますでしょうか。

(ひでちゃん) 2016/06/22(水) 17:00


いや、何度も書いていますが、fsoとはExcelにないものなので、オブジェクト宣言が必要なのです。
どこでMoveFileを見つけましたか? そのページは再度見直して、宣言部分を見つけるように書きましたが、なぜ無視するのですか?

もっと言うと、MoveFileは初心者が使うべき命令ではないです。Excel VBAには Nameステートメントという、ファイル移動できる命令が存在するのに、なぜわざわざ使い方の難しい外部オブジェクトにしたのでしょうか。
(???) 2016/06/22(水) 17:05


やはり、どう書き換えたらよいのか分かりませんので、手動でやります。
ありがとうございました。
(ひでちゃん) 2016/06/22(水) 17:46

コメント返信:

[ 一覧(最新更新順) ]


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