• ベストアンサー

数階層のあるフォルダのコピーを 簡単にするVBA

数階層のあるフォルダのコピーを 簡単にするVBAのプログラムについての ご質問です たとえばフォルダがみっつ、フォルダA フォルダB、フォルダCとあるとします これらのなかには人物のIDと対応するフォルダがあり それぞれのフォルダには、そのIDの人物に関する書類pdfが 入っています たとえばフォルダAにそのサブフォルダとして サブフォルダ1があり、そのなかにpdfファイルがいくつかあります サブフォルダ2も同様です サブフォルダ3,4,・・・・ フォルダBではサブフォルダがサブフォルダ_あ サブフォルダ_い,,, とあり、さらにサブフォルダ_あのなかにIDに対応するサブサブフォルダ11, 12.13とあり それぞれに多種のpdfファイルが入っています なかには例えばですが、サブフォルダ_いのなかにも、さきほどのフォルダAのなかにあったID2に対応するサブフォルダ2が入っています。 これらをすべて統括するような総合フォルダにIDに対応するフォルダだけで まとめあげたいという目的なのですが、 上記のフォルダ2のように別の上層階のフォルダから移動するときに、上書きをするか、別名で保存するか問われますが、フォルダ2で統一して、そのかなのpdfファイルに同名のファイルがあれば、片方をそのまま もう一方を---(1)のような ファイル名に変換して上書きされないようにしたく思います 数百のフォルダがあるので、なんとかコードで作れないか お尋ねしたく思います わかりにくい説明ですみません 簡単な図示を添付致します すみません 宜しくお願い致します 言い方を変えますと、 個人それぞれがID番号を持っていて、ID番号が名称の フォルダがあり、そのなかにpdfファイルが任意の数、格納されており、 そのID対応のフォルダが、いくつかのフォルダのなかに分散されていて、 その階層は一定ではないですが、IDフォルダは各フォルダの最下層にあるものであり、 最終的にはすべてのIDgフォルダをひとつの統合フォルダにまとめあげたい。 なかには別フォルダのなかに重複して、あるIDフォルダによっては分散しているので 統合するときに上書きを問われてしまう それを ひとつのIDフォルダに統合し、そのなかのpdfファイルも上書きはしないで 別名保存で そのIDフォルダに保存したい というわけです かえってわかりにくくなったかもしれません 宜しくお願い致します

質問者が選んだベストアンサー

  • ベストアンサー
  • luka3
  • ベストアンサー率74% (308/414)
回答No.3

どうしてもVBAでなければならないのでしょうか。 一度だけ統合してしまえばいいので、言語にこだわる必要がない気がしまして。 ちょうど先週、ファイルを整理するものを作っていたのでそれを少し改造しました。 下記のプログラムをコピーしてメモ帳かテキストエディタに貼り付けて、 『 統合.js 』といったファイル名で保存し、ダブルクリックで実行して下さい。 保存する際は、メモ帳なら文字コードを『ANSI』、エディタなら『シフトJIS』で保存してください。 余計なお世話かもしれませんが、コピーしたファイル名の結果を log.txt に保存します。 var WShell = WScript.CreateObject("WScript.Shell"); var fso = WScript.CreateObject("Scripting.FileSystemObject"); var ForReading=1, ForWriting=2, ForAppending=8; var slog = ""; // .jsでは \ を使う時2つ続けて \\ にします var srcDir = "C:\\統合元フォルダ名\\*.pdf"; // <= 統合元のフォルダ名と対象の拡張子 var dstDir = "C:\\統合先フォルダ名\\"; // <= 統合先のフォルダ名 var files = GetFileList(srcDir); for (var ia=0; ia<files.length; ia++) CopyFile(files[ia], dstDir); if (slog) WriteFile("log.txt", slog); Err("作業終了"); function GetFileList(pat) { // 指定ファイルの一覧を取得して配列で返す var tmpfile = "tmp$$$.$$$"; WShell.Run('%comspec% /c dir /s /on /b "' + pat + '">'+tmpfile, 8, true); if (!fso.FileExists(tmpfile)) Err("not found "+tmpfile); var str = ReadFile(tmpfile); fso.DeleteFile(tmpfile); return str.split(/\r?\n/); } function CopyFile(filename, dstDir) { // ファイルコピー if (!fso.FileExists(filename)) return ; var m = filename.match(/.*\\(.*)\\(.*)$/); // ファイル名と親フォルダの名前を取得 var newdir = dstDir+m[1]; // コピー先のフォルダ名 var newname = MakeNewName(m[2], newdir); // 新しいファイル名 if (!fso.FolderExists(newdir)) fso.CreateFolder(newdir); // フォルダが無ければ作成 fso.CopyFile(filename, newname); slog += filename + "\r\n => " + newname + "\r\n"; } function MakeNewName(name, pdir) { // コピー先の名前を返す 重複する場合は (1) を付加 var newname = fso.BuildPath(pdir, name); if (fso.FileExists(newname)) { // 同じ名前が存在するか var basename = fso.GetBaseName(name); // ファイル名主部 var ext = "."+fso.GetExtensionName(name); // ファイル名拡張子 for (var ic=1; ; ic++) { newname = fso.BuildPath(pdir, basename+" ("+ic+")"+ext); if (!fso.FileExists(newname)) break; // 存在しなければ終了 } } return newname; } function ReadFile(filename) { // テキストファイルを読み込んで返す var s = ""; if (fso.FileExists(filename) && fso.GetFile(filename).Size>0) { var ts = fso.OpenTextFile(filename,ForReading,true); s = ts.ReadAll(); ts.Close(); } return s; } function WriteFile(filename, s) { // テキストファイルを書き込む var ts = fso.OpenTextFile(filename,ForWriting,true); ts.Write(s); ts.Close(); } function Err(msg) {WScript.Echo(msg); WScript.Quit();}

全文を見る
すると、全ての回答が全文表示されます。

その他の回答 (3)

  • luka3
  • ベストアンサー率74% (308/414)
回答No.4

No.3です。補足です。 保存してすぐ実行するように書きましたが、srcDir dstDirの所は書き換えてから実行してください。 srcDirは下層のサブフォルダの中にあるpdfも全て捜索しますので、フォルダAの1つ上のフォルダを指定してください。

全文を見る
すると、全ての回答が全文表示されます。
  • HohoPapa
  • ベストアンサー率65% (454/692)
回答No.2

私だったら、次のような対応をします。 作業1: 統合したいファイルたちのフォルダー、ファイル名などの一覧をリストアップする 作業2: このリストを指摘のID順、ファイル名順に並べ替える 作業3: このリストのファイル名の重複したレコードに、複写先のファイル名をセットする つまり、 >もう一方を---(1) を付加する処理です。 作業4: このリストに従い、指定したフォルダーにファイルを複写する。 試しに、作業1,2を行うVBAのコードを書いてみました。 このマクロで期待のリストアップまでできればゴールは近いと思います。 なお、このマクロは実行の都度、Sheet1に追記しています。 再処理する場合は、Sheet1を空にしてから実行してください。 見ればわかると思いますが、各列に格納している内容を列挙します。 1列目:ファイルの格納フォルダー 2列目:最深フォルダーの親フォルダー 3列目:最深フォルダー これがIDってことと思います。 4列目:ファイル名 5列目:ファイル名(拡張子以外) 6列目:拡張子  Option Explicit 'Microsoft Scripting Runtime を参照設定 Dim PutRow As Long Dim PutSh As Worksheet Sub sample() Set PutSh = ThisWorkbook.Sheets("Sheet1") If PutSh.Cells(1, 1).Value = "" Then PutRow = 1 Else PutRow = PutSh.Cells(Rows.Count, 1).End(xlUp).Row End If getFilesRecursive "D:\TESTA\Sample" '<==ここに親フォルダーを記述 PutSh.Select Cells.Select PutSh.Sort.SortFields.Clear PutSh.Sort.SortFields.Add2 Key:=Range("C1:C1") _ , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal PutSh.Sort.SortFields.Add2 Key:=Range("D1:D1") _ , SortOn:=xlSortOnValues, Order:=xlAscending, DataOption:=xlSortNormal With PutSh.Sort .SetRange Range("A1:F30000") .Header = xlGuess .MatchCase = False .Orientation = xlTopToBottom .SortMethod = xlPinYin .Apply End With End Sub Sub getFilesRecursive(path As String) Dim fso As FileSystemObject: Set fso = New FileSystemObject Dim objFolder As folder Dim objFile As file 'フォルダ配下のフォルダ一覧を取得 For Each objFolder In fso.GetFolder(path).SubFolders getFilesRecursive (objFolder.path) Next 'フォルダ配下のファイル一覧を取得 If isDeepDir(fso.GetFolder(path)) = True Then For Each objFile In fso.GetFolder(path).Files execute objFile, path Next End If End Sub Sub execute(f As file, p As String) Dim wStr1() As String Dim wStr2 As String Dim ACnt As Long Dim c As Long Dim fso As New Scripting.FileSystemObject Dim filePath As String Dim ExtentionName As String wStr1 = Split(p, "\") ACnt = UBound(wStr1) For c = 0 To ACnt - 1 wStr2 = wStr2 & wStr1(c) & "\" Next c PutSh.Cells(PutRow, 1).Value = p PutSh.Cells(PutRow, 2).Value = wStr2 PutSh.Cells(PutRow, 3).Value = wStr1(ACnt) PutSh.Cells(PutRow, 4).Value = f.Name ExtentionName = fso.GetExtensionName(f) PutSh.Cells(PutRow, 5).Value = Left(f.Name, Len(f.Name) - Len(ExtentionName) - 1) PutSh.Cells(PutRow, 6).Value = ExtentionName Set fso = Nothing PutRow = PutRow + 1 End Sub '//フォルダーが子フォルダーを持たないフォルダーか?を判定する関数 Function isDeepDir(tgDir As String) As Boolean Dim fso As FileSystemObject: Set fso = New FileSystemObject Dim objFolder As folder Dim HitCnt As Long HitCnt = 0 For Each objFolder In fso.GetFolder(tgDir).SubFolders HitCnt = HitCnt + 1 Next If HitCnt = 0 Then isDeepDir = True Exit Function End If End Function 期待通りなら、作業3,4のコードを書きます。

全文を見る
すると、全ての回答が全文表示されます。
  • t_hirai
  • ベストアンサー率27% (171/613)
回答No.1

ランサーズとかでエンジニアさんに依頼するとか。。。

sushidokei
質問者

お礼

ランサーズ>>そういうのがあるのですね 有り難うございました。

Powered by GRATICA
全文を見る
すると、全ての回答が全文表示されます。

関連するQ&A

  • 何階層もあるフォルダツリー内に散らばったファイルをひとつのフォルダにコピーするソフト

    たとえば、Aと言う名のフォルダが頂点にあり、その中に10数個のフォルダがあります。その10数個のフォルダそれぞれにも複数のフォルダがあるとします。そしてそのフォルダそれぞれに何かしらのファイルが存在しています。 このファイルをひとつのフォルダに移動、またはコピーをしたいのですが、手動でやっていたのでは時間がかかるし、見落としもありえます。 自動でやってくれるフリーソフトなどはないのでしょうか? ちなみに、散らばったファイルには同名ファイルも存在したりします。それらがひとつのフォルダに移動されるわけですが、そのとき、勝手に上書きしたりせず、ちゃんと聞いてくるようなソフトを希望です。 何をやりたいかと言うと、長年にわたってため続けたiTunesの保存フォルダをリフレッシュしたいのです。

  • Windows7 フォルダの上書きコピーについて

    Windows7のフォルダの上書きコピーについて質問です。 ファイルサーバにフォルダAがあり、中にファイル1があります。 クライアントPCのフォルダAの中には ファイル1-2、ファイル2、ファイル3、ファイル4、ファイル5があった場合 フォルダAをファイルサーバからクライアントへ『フォルダごとコピー』すると、 『統合しますか』の次に『コピーして置き換える』を選択してもフォルダBのファイル1が更新されるだけで ファイル2、ファイル3、ファイル4、ファイル5が削除されません。 ファイル2、ファイル3、ファイル4、ファイル5を削除するにはどういったコピーをすれば良いでしょうか。 フォルダコピーをしたときに中身も上書きするためにはどうしたら良いでしょうか。 ファイルサーバのフォルダA、ファイル1をフォルダごとクライアントに上書きコピーしたいです。 XPだとフォルダ内ごと上書きできたと思うのですが、7だとできません。 ご存知の方がいらっしゃいましたらご教授願います。

  • パソコンのすべてのファイルとフォルダが上書きできない!

    パソコンの全てのファイルとフォルダが上書きできません!フォルダ名と上書き保存しようとすると 『保存できません。ファイルがロックされています。windowsエクスプローラーのプロパティコマンドで、ファイルのロックを解除してください。ID=-45』 そこでプロパティを見ると読み取り専用にするに■の緑になってる。 だからそこを空白にし直して適用&OKを押して大丈夫かと思いきや もう一度プロパティを開くと、同じ状態です。 上書き保存できないので、全然仕事になりません。(とりあえずは別名保存しまくってます。) 誰か助けてくださいましm(_ _)m

  • フォルダ作成と別名保存【VBA】

    教えてください 現在、下の2つのマクロを使っています。 「O27」の値でフォルダを作るものとブックを別名保存するものです。 これを1つにまとめたいのですが単純に1つにまとめるとフォルダは作成されるのですがブックの別名保存がセルの値を参照してくれません。 また、MkDir でフォルダを作成すると同じ名前のフォルダが先にあるとエラーになってしまいます。 この2点を解消できる方法はないでしょうか? よろしくお願いいたします。 Sub 別名フォルダ() MkDir Worksheets("オーダーシート").Range("O27").Value End Sub Sub 別名保存() Application.Dialogs(xlDialogSaveAs).Show Arg1:=Range("O27").Value End Sub

  • フォルダのコピーについて

    Dドライブに保存したデータを外付けのハードディスクにコピーする時に、同名のファイルやフォルダがあると毎回「上書きしますか?」 と聞かれるんですが、元のフォルダに新しく保存したデータだけコピーするにはどうしたらよいでしょうか? 例えば、Dドライブにa,b,c,d,e,f,gとファイルがあるとします。 外付けにはa,b,c,dはすでにコピーしてありますが、e,f,gはまだしていません。この状態でe,f,gだけコピーするやり方を教えて頂きたいのですが…すべて上書きだととても時間がかかってしまうし、単純に新しいデータだけ選択してコピーすればいいんですが、フォルダの中身コピー元とコピー先でがバラバラに並んでいるので抽出するのが大変なので… どなたかよろしくお願いします。

  • 3つのフォルダをコピーしたい

    3つのフォルダがあります。(1)A・B・Cファイル(2)A・B・Dファイル(3)B・C・D・Eファイルの3種類をまとめたA・B・C・D・Eファイルのフォルダを作成したいのですが、エクスプローラーだと上書きを1つずつすれば、良いのでしょうが自動でまとめれるソフトがあるのでしょうか?

  • VBA PDFを同じフォルダに保存する

    EXCELの差し込み印刷でPDFファイルを出力する方法 https://excel.kuuneruch.com/sasikomi-pdf-select/ 保存場所を同じフォルダに保存したいのですが、どうしたらよいでしょうか? '⑥ひな形シートでPDFを作成する(作成PDFファイル名を指定する) Call CreatePdfFile("D:\100_PDF\" & .Range("A" & nowRow) & ".pdf")

  • イラストレーターCS2でPDFを編集したいのですが

    イラストレーターCS2でPDFファイルをちょっとだけ編集して、 そのままPDFのまま保存したいのですが、イラストレーターCS2の保存が できないようになっています。これはプロテクトが働いているのでしょうか?別名なら保存が可能なのですが、別名ですると複数枚あったPDFファイルが1枚になって保存されてしまいます。 また、複数枚のPDFファイルを1つに統合するフリーウェアはないのでしょうか?

  • 同名のファイル 上書きにならないように

    宜しくお願い致します。 複数のフォルダのなかにある 複数のファイルを ひとつの新規のフォルダにすべてコピーするという作業をするときに 同名のファイルがあると 上書きするかという ダイアログが でてきますが これを 上書きでなく 別名のファイルにして 当該のフォルダに 保存したいのですが 元フォルダにおいて 別名に どちらかをしてから コピーするというのは 多数の場合は 手間が かかります 自動的に 同名ファイルであっても どちらかの名前を 変更して 上書きが 起こらないように 保存できる ソフト ご存知のかた 教えてください 同名ファイルは 3つ以上のこともありえます 宜しくお願い致します。

  • 上書き保存できなくて困っています。

    上書き保存できなくて困っています。 会社でネットワークが組まれている共有フォルダの中のファイルが上書き保存できません。 エクセルだと“ファイルを保存できませんでした” ワードだと“ネットワークまたはファイルアクセス権のエラーです。ネットワーク接続が切断された可能性があります” というメッセージがでます。 デスクトップなど、そのフォルダの外に別名で保存し、それをそのフォルダに入れると上書きできます。 どうすれば今まで通り普通に上書き保存できるのでしょうか。