GoogleAppsScript
GoogleDrive
googleform

Google Drive:フォルダ丸ごとコピー:フォルダ階層下のすべてのファイル・フォルダを同じフォルダ構造のまま一度にコピー(GoogleFormでのメニュー付き)

GoogleDriveのフォルダ丸ごとコピー

できること

 GoogleDrive上で,次のようなフォルダ構造
1.png
があったとして,「フォルダ1」を階層下をすべて含んで,
2.png
のようにコピーします。図では各フォルダ配下にフォルダが1つしかありませんが,複数存在してもその通りにコピーします。
 GoogleDriveは同じフォルダ名・ファイル名が許容されているため,コピーしたフォルダのルートフォルダ名だけは自動で「(コピー)」を付けるか,事前にフォルダ名を指定しておきます。
 なお,「フォルダ1(コピー)」を作成する場所(フォルダ)は任意です。図のように「フォルダ0」の配下でも構いませんし,IDを事前に調べておくことで任意のフォルダを指定できます。
 Windowsだとエクスプローラでドラッグ一発ですが,GoogleDriveはファイルを一つずつコピーしては移動してファイル名を変更する・・・なんて繰り返さなければならないので,作ってみました。これでバックアップを取るのがとても楽になります。
 コピーするフォルダと,コピー先フォルダは,IDをGoogleFormに入力します。以前公開した,GoogleSpreadSheet上で作業するよりは使い勝手がとてもよいです。

実現方法

GoogleForm

 GoogleFormで次のようなアンケートを作ります。この後のソースリストの関係で,「コピー元フォルダのID」,「コピー先フォルダのID」,「新規フォルダ名」の名称については,変更しないでください。また「コピー元フォルダのID」,「コピー先フォルダのID」は入力必須に設定します。「新規フォルダ名」は入力必須にしません。

1.png

GoogleAppsScriptプログラム(フォルダコピープログラム)

 点が縦3つ並んだ部分(メニュー)をクリックし,「スクリプトエディタ」を起動します。

21.png

 「コード.gs」に元々入っていた4行ほどのプログラムは削除し,次のプログラムをコピー・ペーストします。

フォルダ丸ごとコピー
function submitForm(e){//フォームが送信されたら呼び出される,重複処理を避ける
  var lock = LockService.getScriptLock();//ロックサービスのオブジェクトを生成
  try{
    lock.waitLock(30000);//複数のフォーム送信がほぼ同時にあった時,遅い方に最大30秒待ってもらう
    Logger.log("コピー作業開始");
    main(e);
  }catch(err){
    Logger.log("発生したエラー:"+err);
  }finally{
    lock.releaseLock();//次の送信のためにロック解除
    Logger.log("コピー作業終了");
  } 
}

function main(e){
  var itemResponses = e.response.getItemResponses(); 
  var dstFolderName = "";
  for (var i = 0; i < itemResponses.length; i++){
    var itemResponse = itemResponses[i]; 
    var question = itemResponse.getItem().getTitle(); 
    var answer = itemResponse.getResponse(); 
    if(question == "コピー元フォルダのID"){
      var srcFolderId = answer;
      var srcFolder = DriveApp.getFolderById(srcFolderId);
      var srcFolderName = srcFolder.getName();
    }
    if(question == "コピー先フォルダのID"){
      var dstFolderId = answer;//このフォルダー内に,フォルダーのコピーを作る
      var dstFolder = DriveApp.getFolderById(dstFolderId);
    }
    if(question == "新規フォルダ名"){
      dstFolderName = answer;
      Logger.log(dstFolderName);
    }
  }

  if(dstFolderName=="") dstFolderName = srcFolderName+"(コピー)";
  var newFolder = dstFolder.createFolder(dstFolderName);
  copy(srcFolder, newFolder);//コピー元,コピー先
}  

function copy(srcFolder, newFolder){
  var srcFiles = srcFolder.getFiles();//フォルダ内ファイルをゲット
  while(srcFiles.hasNext()) {
    var srcFile = srcFiles.next();
    Logger.log(srcFile.getName());
    srcFile.makeCopy(srcFile.getName(), newFolder);
  }
  var srcFolders = srcFolder.getFolders();//フォルダ内フォルダをゲット
  while(srcFolders.hasNext()) {
    var nextSrcFolder = srcFolders.next();
    Logger.log(nextSrcFolder.getName());
    var nextNewFolder = newFolder.createFolder(nextSrcFolder.getName());
    copy(nextSrcFolder, nextNewFolder);//再帰
  }
}

 実際の開発画面は次のような感じです。スクリプト名は「フォルダ丸ごとコピー」に設定しています。

22.png

トリガーと承認の設定

 現在のプロジェクトのトリガーを次のように設定して,フォーム送信時に実行されるようにして,保存します。

2.png

3.png

4.png

 承認が必要になりますので,「許可を確認」して,「許可」します。

5.png

6.png

リンクの取得

 フォームの「送信」をクリックします。

23.png

 送信方法で,クリップマークをクリックし,「URLを短縮」をクリック(これはしてもしなくても良いですが,短い方が扱いやすい)して,「コピー」をクリックすると,リンクのURLがクリップボードにコピーされます。ブラウザのURLにコピー・ペーストして一旦アンケートフォームに接続して,ショートカットをデスクトップにでも作っておくと便利です。ブラウザのURL欄の先頭付近をドラッグすると,デスクトップにショートカットを作ることができます。

8.png

GoogleFormの設定

 アンケートフォームの点が縦3つに並んだメニューから,「設定」を選択し,「全般」で,「送信後に編集」を設定しておくと使い勝手が良くなります。

10.png

 「プレゼンテーション」で,「別の回答を送信するためのリンクを表示」はどちらでも良いですが,「確認メッセージ」は,「コピーを作成しました。」としておくと違和感ないです。(^^ )

11.png

フォルダ丸ごとコピーの実行

 先ほどコピーしておいたURLに接続します。ショートカットが作ってあれば,それをダブルクリックして,アンケートに接続します。
 フォームに,丸ごとコピーしたいフォルダのID,コピーを作りたいフォルダのIDを指定して,「送信」をクリックします。ここでは「1」という名前のフォルダ名のID(そのフォルダに入ってURLに表示されるID)と「1」が置かれているフォルダのIDを指定しています。つまり,「1」のコピーを同じ場所に作ります。

9.png

 フォルダIDは,そのフォルダに入った時のURLから知ることができます。「/」より後ろの部分で,「/」は含みません。

40.png

 「送信」すると,次のように,フォルダ「1」に対して,「1(コピー)」が作成されます。「1」の配下のファイル・フォルダもすべてコピーされます。

30.PNG

 次のように,「新規フォルダ名」を指定しておけば,

14.png

 そのフォルダ名で,コピーされます。この図でのtestフォルダの下は,コピー元の「1」の配下の内容と全く同じになります。

32.PNG

 このフォームはGoogleDriveのどこにあっても構いません。コピー元フォルダのIDと,コピー先フォルダのIDを正しく入力すれば,コピーが作成されます。