次のURLでより使いやすくなった,フォルダ丸ごとコピー,を紹介しています。ご参照ください。
https://qiita.com/matsuhandy/items/00bce2397ba8e9ca58e1
#GoogleDriveのフォルダ丸ごとコピー
##できること
GoogleDrive上で,次のようなフォルダ構造
があったとして,「フォルダ1」を階層下をすべて含んで,
のようにコピーします。図では各フォルダ配下にフォルダが1つしかありませんが,複数存在してもその通りにコピーします。
GoogleDriveは同じフォルダ名・ファイル名が許容されているため,コピーしたフォルダのルートフォルダ名だけは自動で「(コピー)」を付けるか,事前にフォルダ名を指定しておきます。
なお,「フォルダ1(コピー)」を作成する場所(フォルダ)は任意です。図のように「フォルダ0」の配下でも構いませんし,IDを事前に調べておくことで任意のフォルダを指定できます。
Windowsだとエクスプローラでドラッグ一発ですが,GoogleDriveはファイルを一つずつコピーしては移動してファイル名を変更する・・・なんて繰り返さなければならないので,作ってみました。これでバックアップを取るのがとても楽になります。
##実現方法
###手順
GoogleSpreadSheetにコピー元やコピー先を指定します。「ツール」「スクリプトエディタ」でコピープログラムを記述して実行します。
###GoogleSpreadSheetにコピー元フォルダ・コピー先フォルダを設定
図のようにGoogleSpreadSheetにコピー元フォルダIDとコピー先フォルダIDを記述します。上の図のようにコピーするのであれば,コピー先フォルダは,「フォルダ0」のIDを指定します。なお,コピー元フォルダ名は書いてあっても無視されます。コピー元フォルダIDに実際に付いている名前が使われます。単なるメモです。
コピー先フォルダ名に何か書いてあればそれをコピーされたフォルダのルートのフォルダ名になります。書いてなければ,コピー元フォルダIDのフォルダ名に「(コピー)」が付けられたものになります。
なおSpreadSheetの名前は,図のように「フォルダコピー」等,わかりやすいものにしておきます。お気づきと思いますが,このSpreadSheet「フォルダコピー」は任意の場所に置けます。私はコピーするフォルダがあるフォルダ,上の図でいうと,「フォルダ0」の配下(「フォルダ1」と同列)に置いています。
フォルダ丸ごとコピーをする際,このSpreadSheet「フォルダコピー」を移動するのは良いのですが,コピーする場合は「フォルダコピー」のIDが変わりますので,ソース中の「XXXXXXXXXXXXXXXXXXXXXXXXXX」の部分も変更します(次節参照)。(どなたか,自分自身のファイルIDを知る方法をご存じでしたら教えてください)
###GoogleSpreadSheetの「ツール」「スクリプトエディタ」でコピープログラムを記述
SpreadSheet「フォルダコピー」の「ツール」「スクリプトエディタ」に次のプログラムを記述します。「XXXXXXXXXXXXXXXXXXXXXXXXXX」の部分は,SpreadSheet「フォルダコピー」のIDをURLからコピー・ペーストします。
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);//再帰
}
}
ここで,「Ssheet.gs」の内容が必要になりますが,これはSpreadseatを扱う自作のクラスです。メンバ関数のすべてが必要ではないのですが,すべてリストしておきます。「Ssheet.gs」は,「ファイル」「新規作成」「スクリプトファイル」で,ファイル名として「Ssheet」を指定します。拡張子「.gs」は勝手に付きます。
//////////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 = 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」を選択し,実行ボタンをクリックします。
「実行の承認」のダイアログが表示されたら,承認します。
##アドバイス等
ご意見・アドバイスなどございましたら,コメント欄にお書きください。