LoginSignup
27
26

More than 5 years have passed since last update.

Google Drive:フォルダ丸ごとコピー:フォルダ階層下のすべてのファイル・フォルダを同じフォルダ構造のまま一度にコピーする

Last updated at Posted at 2018-03-12

 次のURLでより使いやすくなった,フォルダ丸ごとコピー,を紹介しています。ご参照ください。
https://qiita.com/matsuhandy/items/00bce2397ba8e9ca58e1

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

できること

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

実現方法

手順

 GoogleSpreadSheetにコピー元やコピー先を指定します。「ツール」「スクリプトエディタ」でコピープログラムを記述して実行します。

GoogleSpreadSheetにコピー元フォルダ・コピー先フォルダを設定

 図のようにGoogleSpreadSheetにコピー元フォルダIDとコピー先フォルダIDを記述します。上の図のようにコピーするのであれば,コピー先フォルダは,「フォルダ0」のIDを指定します。なお,コピー元フォルダ名は書いてあっても無視されます。コピー元フォルダIDに実際に付いている名前が使われます。単なるメモです。
3.png
 コピー先フォルダ名に何か書いてあればそれをコピーされたフォルダのルートのフォルダ名になります。書いてなければ,コピー元フォルダIDのフォルダ名に「(コピー)」が付けられたものになります。
 なおSpreadSheetの名前は,図のように「フォルダコピー」等,わかりやすいものにしておきます。お気づきと思いますが,このSpreadSheet「フォルダコピー」は任意の場所に置けます。私はコピーするフォルダがあるフォルダ,上の図でいうと,「フォルダ0」の配下(「フォルダ1」と同列)に置いています。
 フォルダ丸ごとコピーをする際,このSpreadSheet「フォルダコピー」を移動するのは良いのですが,コピーする場合は「フォルダコピー」のIDが変わりますので,ソース中の「XXXXXXXXXXXXXXXXXXXXXXXXXX」の部分も変更します(次節参照)。(どなたか,自分自身のファイルIDを知る方法をご存じでしたら教えてください)

GoogleSpreadSheetの「ツール」「スクリプトエディタ」でコピープログラムを記述

 SpreadSheet「フォルダコピー」の「ツール」「スクリプトエディタ」に次のプログラムを記述します。「XXXXXXXXXXXXXXXXXXXXXXXXXX」の部分は,SpreadSheet「フォルダコピー」のIDをURLからコピー・ペーストします。

6.png

フォルダコピー
function folderCopy() {

  var ss = new Ssheet("XXXXXXXXXXXXXXXXXXXXXXXXXX");//フォルダコピー,のspreadsheetのID

  var srcFolderId = ss.getValue(0, 2,2);//コピー元
  var srcFolder = DriveApp.getFolderById(srcFolderId);
  var srcFolderName = srcFolder.getName();

  var dstFolderId = ss.getValue(0, 3,2);//このフォルダー内に,フォルダーのコピーを作る
  var dstFolder = DriveApp.getFolderById(dstFolderId);
  var dstFolderName = ss.getValue(0, 3,3);
  if(dstFolderName=="") dstFolderName = srcFolderName+"(コピー)";//コピー先の最上位フォルダだけ識別しやすくする

  var newFolder = dstFolder.createFolder(dstFolderName)
  Logger.log(newFolder.getName());
  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);//再帰
  }
}

 実際の開発画面は次の通りです。参考にしてください。
7.png

 ここで,「Ssheet.gs」の内容が必要になりますが,これはSpreadseatを扱う自作のクラスです。メンバ関数のすべてが必要ではないのですが,すべてリストしておきます。「Ssheet.gs」は,「ファイル」「新規作成」「スクリプトファイル」で,ファイル名として「Ssheet」を指定します。拡張子「.gs」は勝手に付きます。

Ssheetクラス
//////////Ssheetクラスの定義開始(コンストラクタとメンバ関数で構成)
//Ssheetクラスのコンストラクタの記述
Ssheet = function(id){
  this.id = id;
  this.ssFile = SpreadsheetApp.openById(id);
  this.ssFileName = this.ssFile.getName();
  SpreadsheetApp.setActiveSpreadsheet(this.ssFile);//値を返さない
  this.activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
}
//Ssheetクラスのメンバ関数(メソッド)の定義開始
//spreadsheetのファイル名を返すメソッド
Ssheet.prototype.getFileName = function(){
  return this.ssFileName;
}
//spreadsheetのファイル名を変更するメソッド
Ssheet.prototype.rename = function(newName){
  this.ssFile.rename(newName);
}
//spreadsheetのsheetでrow行cal列にデータを入れるメソッド
Ssheet.prototype.setValue = function(sheet,row,col,value){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var cell = this.activeSheet.getRange(row,col);
  cell.setValue(value);
}
//spreadsheetのsheetでrow行cal列を数値形式にセットするメソッド
Ssheet.prototype.setStdNumFmt = function(sheet,row,col,value){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var cell = this.activeSheet.getRange(row,col);
  cell.setNumberFormat("0");
}
//spreadsheetのsheetでrow行cal列をクリアするメソッド
Ssheet.prototype.clear = function(sheet,row,col,value){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var cell = this.activeSheet.getRange(row,col);
  cell.clear(value);
}
//spreadsheetのsheetからrow行のcal列のデータをもらってくるメソッド
Ssheet.prototype.getValue = function(sheet,row,col) {
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var value = this.activeSheet.getRange(row, col).getValue();
  return value;
}
//背景の色を設定するメソッド
Ssheet.prototype.setBackgroundColor = function(sheet,row,col, r,g,b) {
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var cell = this.activeSheet.getRange(row,col);
  cell.setBackgroundRGB(r,g,b);
}
//spreadsheetのsheet数を指定の数増やすメソッド
Ssheet.prototype.insertSheet = function(num){
  var sheetNum = this.activeSpreadsheet.getNumSheets();
  while(num>sheetNum){
    this.activeSpreadsheet.insertSheet();
    sheetNum++;
  }
}
//spreadsheetの指定sheetを削除
Ssheet.prototype.deleteSheet = function(sheet){
  this.activeSpreadsheet.deleteSheet(this.activeSpreadsheet.getSheets()[sheet])
}
//spreadsheetのsheetの名前をセットするメソッド
Ssheet.prototype.renameSheet = function(sheet,newName){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  this.activeSheet.setName(newName);
}
//spreadsheetの指定sheetの全データを取得
Ssheet.prototype.getValues = function(sheet){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  return this.activeSheet.getDataRange().getValues();//シートの全データを取得
}  
//spreadsheetの指定sheetを取得
Ssheet.prototype.getSheet = function(sheet){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  return this.activeSheet;//シートを返す
}
//spreadsheetの指定sheetの最後の行番号を取得
Ssheet.prototype.getLastRow = function(sheet){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  return this.activeSheet.getLastRow();//最後の行番号を取得
}
//spreadsheetの指定sheetの最後の列番号を取得
Ssheet.prototype.getLastColumn = function(sheet){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  return this.activeSheet.getLastColumn();//最後の列番号を取得
}
//spreadsheetの指定行rowを削除
Ssheet.prototype.deleteRow = function(sheet,row){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  this.activeSheet.deleteRow(row);//行を削除
}
//spreadsheetの指定行rowを挿入
Ssheet.prototype.insertRow = function(sheet,row){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  this.activeSheet.insertRows(row);//行を挿入
}
//spreadsheetの指定列colを削除
Ssheet.prototype.deleteColumn = function(sheet,col){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  this.activeSheet.deleteColumn(col);//列を削除
}
//spreadsheetの指定列colを挿入
Ssheet.prototype.insertColumn = function(sheet,col){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  this.activeSheet.insertColumns(col);//列を挿入
}
//n(0,1,2...)枚目のsheetをアクティブにして,シートのIDを返す
Ssheet.prototype.getSheetIdByNum = function(sheet){
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var sheetId = this.activeSheet.getSheetId();
  return sheetId;
}
//////////Ssheetクラスの定義終了

 実際には,ごく一部しか使ってないので,下記だけでもokなはずです。下記だけを「コード.gs」の一番下に付け足すだけでもokなはずです。

Ssheetクラス
//////////Ssheetクラスの定義開始(コンストラクタとメンバ関数で構成)
//Ssheetクラスのコンストラクタの記述
Ssheet = function(id){
  this.id = id;
  this.ssFile = SpreadsheetApp.openById(id);
  this.ssFileName = this.ssFile.getName();
  SpreadsheetApp.setActiveSpreadsheet(this.ssFile);//値を返さない
  this.activeSpreadsheet = SpreadsheetApp.getActiveSpreadsheet();
}

//spreadsheetのsheetからrow行のcal列のデータをもらってくるメソッド
Ssheet.prototype.getValue = function(sheet,row,col) {
  this.activeSheet = this.activeSpreadsheet.getSheets()[sheet];
  var value = this.activeSheet.getRange(row, col).getValue();
  return value;
}

実行の方法

 SpreadSheetにコピー元,コピー先のフォルダIDを正しく設定後,次の図のように,「コード.gs」を指定して,関数「folderCopy」を選択し,実行ボタンをクリックします。

5.png

 「実行の承認」のダイアログが表示されたら,承認します。

8.PNG

9.png

アドバイス等

 ご意見・アドバイスなどございましたら,コメント欄にお書きください。

27
26
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
27
26