ファイル、フォルダコピー(同期)をエクセル参照して
エクセルで指定したフォルダ間をコピーするツールです。
※エクセルを使用したWSHのツールです。
おそらく今後必要になりそうだったので、先行して作成しました。
あとエラー処理、オープンオフィスの対応がありますが
とりあえずこれで色々試してみたいです。
こちらは往々にこちらを参考させて頂きました。
JScriptでのScripting.FileSystemObjectオブジェクト TIPS - Qiita
まずはコード
//指定ファイルのエクセル、セルB2[コピー元]H2[コピー先]に記載されているパスを元に //フォルダをコピーするツール。 //現在はコピー先のフォルダ、ファイルを一旦削除しています。 //要はフォルダ間を同期する感じです。 //エクセルのセルを増やせばコピーするフォルダが増えます。 //フォルダがなければ、強制的にフォルダを作成します。 //以下注意事項があります。 //1.B2、H2のセルは必ず列で埋めて下さい。間があるとエラーになります。 //2.列に空白は作らないください。これもエラーになります。 //3.一個上のフォルダまで有無は確認しますが、それ以上はエラーとなります。 var fso = new ActiveXObject("Scripting.FileSystemObject"); var Shell = new ActiveXObject("Shell.Application"); var excelApp = WScript.CreateObject("Excel.Application"); var Book = excelApp.Workbooks.Open("C:\\Users\\tommy_on\\Desktop\\Copypath.xls"); var Sheet = Book.WorkSheets("Sheet1"); var usedRange = Sheet.UsedRange; var bottom = usedRange.Rows(usedRange.Rows.Count).Row;//列の一番下取得 for (var i=2; i<bottom+1; i++) { var end_B_cells = Sheet.Cells(i,2).value; var end_H_cells = Sheet.Cells(i,8).value; var Floder = Shell.NameSpace(end_H_cells); if(!fso.FolderExists(end_H_cells)) { ParentFolder(end_H_cells); } else { var DelItems = Floder.Items(); for(var j = 0 ; j<DelItems.count; j++) { var SetItem = DelItems.Item(j); if(SetItem.IsFolder == true) { fso.DeleteFolder(SetItem,true); } else if(SetItem.IsFile == true) { fso.DeleteFile(SetItem,true); } } } fso.CopyFolder(end_B_cells, end_H_cells); } function ParentFolder(end_H_cells) { if (!fso.FolderExists(end_H_cells)) { if (fso.GetParentFolderName(end_H_cells)) { // フォルダが存在しなかったので、親フォルダ生成 createFolder(fso.GetParentFolderName(end_H_cells)); fso.CreateFolder(end_H_cells); } } } Book.Close(); fso = null; excelApp.Quit(); excelApp = null;
こんな感じです。
流れとしては、
まずはコピー元とコピー先を記入したエクセルが必要です。
こんな感じ
フォルダ的はこんな感じです。
エクセルのセル【B1以降】【H1以降】を参照して
コピーする感じです。
この環境ができれば、あとは上記コードのエクセルパスを変更後
JSで保存して実行すれば、BパスからHパスへフォルダ、ファイルがコピーされてると思います。
コードのコメント欄に書いてますが
注意事項があります。
1.B2、H2のセルは必ず列で埋めて下さい。間があるとエラーになります。
→BとHに必ずセルが埋まっている事が前提になっています。ないとエラーで止まりますので・・
2.列に空白は作らないください。これもエラーになります。
→使用している、列を取得している為、間に空白があるとそこが最後の列として扱われます。
3.一個上のフォルダまで有無は確認しますが、それ以上はエラーとなります。
→これは仕様です。もっと親を伸ばすことはできますが、しません。
こんな感じでした。
ではコードで手こずった部分をメモ変わりに書いていきます。
まずは、列の取得。
今回はB,Hで使用している列数ですね。
var usedRange = Sheet.UsedRange; var bottom = usedRange.Rows(usedRange.Rows.Count).Row;//列の一番下取得
「UsedRange」で使用しているセルを取得し、「Rows.Count」で一番までカウントしてます。
これによって一番のセルまで取れてる訳ですね。
これはめちゃくちゃハマりました。
ってかこれであってるか未だに自信ありません。
あとFolderExitで親フォルダも無い時の挙動です。
これはおもっきり上記リンクを参考にさせてもらってます。
function ParentFolder(end_H_cells) { if (!fso.FolderExists(end_H_cells)) { if (fso.GetParentFolderName(end_H_cells)) { // フォルダが存在しなかったので、親フォルダ生成 createFolder(fso.GetParentFolderName(end_H_cells)); fso.CreateFolder(end_H_cells); } } }
SIでも同様のことやってたんですが
なぜか上手くいかなったので参考にさせてもらってます。
内容は非常に簡単で
「親フォルダ取得」→「無かった作成」→「フォルダを取得」
を繰り返しているだけ。
まぁ一応苦戦したので、忘れないように・・・
とまぁこんな感じで作成しました。
今後はエラー処理を入れ込みがいるかな?
あと、この手のツールはC#でアプリケーションとして作成したいですね。
以上です。