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

#GoogleDriveのフォルダ丸ごとコピー
##できること
　GoogleDrive上で，次のようなフォルダ構造
![1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/6121dc41-4754-aa63-f595-af3938e21131.png)
があったとして，「フォルダ1」を階層下をすべて含んで，
![2.png](https://qiita-image-store.s3.amazonaws.com/0/146927/3007353e-f4f4-cf9c-c4c7-d5a9ccd0adee.png)
のようにコピーします。図では各フォルダ配下にフォルダが1つしかありませんが，複数存在してもその通りにコピーします。
　GoogleDriveは同じフォルダ名・ファイル名が許容されているため，コピーしたフォルダのルートフォルダ名だけは自動で「（コピー）」を付けるか，事前にフォルダ名を指定しておきます。
　なお，「フォルダ1（コピー）」を作成する場所（フォルダ）は任意です。図のように「フォルダ0」の配下でも構いませんし，IDを事前に調べておくことで任意のフォルダを指定できます。
　Windowsだとエクスプローラでドラッグ一発ですが，GoogleDriveはファイルを一つずつコピーしては移動してファイル名を変更する･･･なんて繰り返さなければならないので，作ってみました。これでバックアップを取るのがとても楽になります。
　コピーするフォルダと，コピー先フォルダは，IDをGoogleFormに入力します。以前公開した，GoogleSpreadSheet上で作業するよりは使い勝手がとてもよいです。

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

![1.png](https://qiita-image-store.s3.amazonaws.com/0/146927/1629842f-311f-f8f6-a657-0a4458bb2cd4.png)

###GoogleAppsScriptプログラム（フォルダコピープログラム）

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

![21.png](https://qiita-image-store.s3.amazonaws.com/0/146927/eaab9099-2360-c4f4-4974-d8c4bea18de7.png)

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

```javascript:フォルダ丸ごとコピー
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](https://qiita-image-store.s3.amazonaws.com/0/146927/ef101412-c7a6-7a9f-314e-f3c6e08905a4.png)

###トリガーと承認の設定

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

![2.png](https://qiita-image-store.s3.amazonaws.com/0/146927/2adfde81-2b7f-5129-7490-b9f6749c2b06.png)

![3.png](https://qiita-image-store.s3.amazonaws.com/0/146927/dde85394-cb4d-30c4-20ba-d11b71f8629e.png)

![4.png](https://qiita-image-store.s3.amazonaws.com/0/146927/2f837d0e-ebd6-d1cc-5a36-8b68be0dd3d3.png)

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

![5.png](https://qiita-image-store.s3.amazonaws.com/0/146927/4af762af-0fb9-ff95-9c53-fe7c2f8c598a.png)

![6.png](https://qiita-image-store.s3.amazonaws.com/0/146927/bc0a48c9-c609-d257-24ad-1a6a2bc40e1b.png)

###リンクの取得

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

![23.png](https://qiita-image-store.s3.amazonaws.com/0/146927/4df16c90-3beb-0d47-f813-66ca56f49cec.png)

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

![8.png](https://qiita-image-store.s3.amazonaws.com/0/146927/a0ed39c2-db83-cac9-3559-2896232aae27.png)

###GoogleFormの設定

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

![10.png](https://qiita-image-store.s3.amazonaws.com/0/146927/3e9774d6-6153-ce89-a77c-a13e7915979c.png)

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

![11.png](https://qiita-image-store.s3.amazonaws.com/0/146927/51d936a5-e13a-76d0-209a-6611cd3da6e7.png)

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

![9.png](https://qiita-image-store.s3.amazonaws.com/0/146927/a3f9f8ae-131d-3f64-c3c9-0ec2d1600182.png)

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

![40.png](https://qiita-image-store.s3.amazonaws.com/0/146927/a8b7a412-a023-c1dd-ec24-53fc987ab0a9.png)

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

![30.PNG](https://qiita-image-store.s3.amazonaws.com/0/146927/a424c722-8d2f-24fb-e598-3afb94edf04c.png)

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

![14.png](https://qiita-image-store.s3.amazonaws.com/0/146927/73bc50fe-a736-4dcd-f8d0-9fe09d23957d.png)

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

![32.PNG](https://qiita-image-store.s3.amazonaws.com/0/146927/df95a336-850f-55e6-a9d3-d5dbc1019fc3.png)

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