見出し画像

【GAS】Google Apps Script 活用事例 Google Driveのフォルダ一覧を取得する方法

スクリーンショット 2020-04-11 12.56.42

フォルダ一覧のIDを書き出して、そのフォルダに、特定のスプレッドシートを移動したいと思う場面があり、こんな感じのスクリプト書いてみました。

Google Driveのファイル一覧をスプレッドシートに書き出したりするスクリプトは、自分以外の人もたくさん記事に残してくれているのですが、より深い下位階層のフォルダを取得したり、この記事にしかない事を頑張って書いたつもりです。よかったらどうぞ!!

ソースコード

function getFolders() {
 const folder       = DriveApp.getFolderById('**************');
 const childFolders = folder.getFolders();
 console.log(folder.getName());
 console.log(childFolders);
 
 let foldersArray = [];
 
 while (childFolders.hasNext()) {
   const childFolder      = childFolders.next();
   const childFolderUrl   = childFolder.getId();
   const childFolderName  = childFolder.getName().replace('2019_','');
   foldersArray.push([childFolderName, childFolderUrl]);
 }
 
 foldersArray.sort(compareFunc);
 console.log(foldersArray);
}

/*while文を使うと、順番どおりにならないため、数値でSORTする*/
function compareFunc(a, b) {
 return a < b ? -1:1;
}

Test > 2019_01......のようにフォルダが格納されており、DriveApp.getFolderByIdで、Testフォルダを取得して、その子フォルダを取得しています。

const childFolders = folder.getFolders(); の返り値

スクリーンショット 2020-04-11 12.58.57

「何やねん、{} って、舐めとんのか?」と思ったのは、僕だけではないはずです。これは、これで正しく取得出来ているようです。.getFolders();だけでは、フォルダ名やIDの取得が思い通りに出来ないようです。

ちなみにファイルだけを書き出したい時は、こんな感じ

function getFiles() {
 const folder = DriveApp.getFolderById('*******************');
 const files  = folder.getFiles();
 console.log(folder.getName());
 console.log(files);
 
 let filesArray = [];
 
 while (files.hasNext()) {
   const file    = files.next();
   const fileUrl = 'https://drive.google.com/file/d/' + file.getId() + '/view';
   filesArray.push([file, fileUrl]);
 }//while
 
 console.log(filesArray);
 
 
 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
 const sheet       = spreadsheet.getSheetByName('チームドライブ');
 sheet.getRange(1, 1, filesArray.length, filesArray[0].length).setValues(filesArray);
}//end

スプレッドシートに書き出す処理も追加

function getFolders() {
 const folder       = DriveApp.getFolderById('*****************');
 const childFolders = folder.getFolders();
 console.log(folder.getName());
 console.log(childFolders);
 
 let foldersArray = [];
 
 //日付の連番通りに並び替えたい場合、2019が不要なので、一度消去する処理をする。
 while (childFolders.hasNext()) {
   const childFolder      = childFolders.next();
   const childFolderUrl   = childFolder.getId();
   const childFolderName  = childFolder.getName().replace('2019_','');
   foldersArray.push([childFolderName, childFolderUrl]);
 }//while
 
 console.log(foldersArray);
 foldersArray.sort(compareFunc);
 console.log(foldersArray);
 
//SORT後、.replace('2019_','')によって、なくなってしまった2019を再び、くっつける
 let newArray = [['フォルダー名','Google Drive フォルダID','URL']];
 
 for(let i = 0; i < foldersArray.length; i++){
   const originalName = '2019_' + foldersArray[i][0];
   const driveUrl     = 'https://drive.google.com/drive/u/0/folders/' + foldersArray[i][1];
   newArray.push([originalName, foldersArray[i][1], driveUrl]);
   
 }//for
 
 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
 const sheet       = spreadsheet.getSheetByName('test');
 sheet.getRange(1, 1, newArray.length, newArray[0].length).setValues(newArray);
}//folder

/*while文を使うと、順番どおりにならないため、数値でSORTする*/
function compareFunc(a, b) {
 return a < b ? -1:1;
}

上記は、もう少し短くなりそうな気がします。しかし、思い通りに書き出す事が出来ました。

スクリーンショット 2020-04-11 13.01.18

/*前述の.replace('2019_','') で、2019がなくなってしまったため、再びくっつける*/
 let newArray = [['フォルダー名','Google Drive フォルダID','URL']];
 
 for(let i = 0; i < foldersArray.length; i++){
   const originalName = '2019_' + foldersArray[i][0];
   const driveUrl     = 'https://drive.google.com/drive/u/0/folders/' + foldersArray[i][1];
   newArray.push([originalName, foldersArray[i][1], driveUrl]);
   
 }//for

この部分って不要じゃね?と思って外してみた結果

スクリーンショット 2020-04-11 20.12.28

ま、冗長な記述かもしれないですが、入れておいた方が良さそうですね.....。

もう一階層、奥へ潜りたい

スクリーンショット 2020-04-11 13.21.00

Test  >  2019_01  >  CSV

つまり、図のように、CSV、Document、PDF、Spreadsheetというフォルダを取得したいと思います。while文を入れ子にしたいと思います。ちょっと、頭がフル回転していないと書けない系のスクリプトですね.....。

下位階層のフォルダを取得するスクリプト

function getFolders2() {
 const folder       = DriveApp.getFolderById('*********************');
 const childFolders = folder.getFolders();
 console.log(folder.getName());
 console.log(childFolders);
 
 let foldersArray = [];
 
 while (childFolders.hasNext()) {
   const childFolder       = childFolders.next();
   const childFolderName   = childFolder.getName();
   const childFolderId     = childFolder.getId();
   const innerChildFolder  = DriveApp.getFolderById(childFolderId);//2019_01など
   const innerChildFolders = innerChildFolder.getFolders();
     
     while(innerChildFolders.hasNext()){
       const targetFolder      = innerChildFolders.next();
       const targetFolderName  = targetFolder.getName();
       const targetFolderId    = targetFolder.getId();
       const targetFolderUrl   = 'https://drive.google.com/drive/u/0/folders/' + targetFolderId;
       foldersArray.push([childFolderName, targetFolderName, targetFolderId, targetFolderUrl]);
     }//inner_while
 }//while
 
 foldersArray.sort(compareFunc);
 foldersArray.unshift(['親フォルダ', '子フォルダ','フォルダID','URL'])
 console.log(foldersArray);
 
 const spreadsheet = SpreadsheetApp.getActiveSpreadsheet();
 const sheet       = spreadsheet.getSheetByName('test2');
 sheet.getRange(1, 1, foldersArray.length, foldersArray[0].length).setValues(foldersArray);
 
}

変数名を何にするか、迷う......。うーん.....。

スクリーンショット 2020-04-11 20.23.12

これで、やっと目的のフォルダIDを取得出来ました。これをgetDataRange()などで読み取り、for文で代入し続けるスクリプトを書けば、スタッフの人数分フォルダに手動で入れたりする事を完全に自動化出来ます!!15人とかいたら、15回ですからね......。

複製したSpreadsheetの一覧から、openByUrlでSpreadsheetを取得し、それを目的のフォルダへ移動するスクリプト

function moveFile() {
 /*複製したSpreadsheet一覧*/
 const spreadsheet    = SpreadsheetApp.getActiveSpreadsheet();
 const sheet          = spreadsheet.getSheetByName('Spreadsheet');
 const values         = sheet.getDataRange().getValues();
 values.shift();
 const sourceFolderId = values[1][3];//移動前のファイルが格納されているフォルダ
 
 /*Google Driveのフォルダ一覧*/
 const folderList   = spreadsheet.getSheetByName('Google Drive');
 const folderDetail = folderList.getDataRange().getValues();
 const year         = getYear();
 //  console.log(folderDetail);
 
 for(let i = 0; i < values.length; i++){
   const targetSpreadsheet = SpreadsheetApp.openByUrl(values[i][2]);//URLでspreadsheetを取得
   const spreadsheetId     = targetSpreadsheet.getId();
   const spreadsheetName   = values[i][1];
   
   console.log(targetSpreadsheet.getName());//名前
   console.log(spreadsheetId);//spreadsheetId
   console.log(spreadsheetName);//スタッフの名前
   
   //スタッフの名前を含んだフォルダを探して移動する。
   for(let j = 0; j < folderDetail.length; j++){
     if(folderDetail[j][0].indexOf(spreadsheetName) !== -1 && folderDetail[j][1] === year){
       
       //getRangeの引数に対応させるために、1を足す
       const row = j + 1;
       const folderId = folderList.getRange(row, 3).getValue();
       //folder IDの取得
       console.log(folderId);
       
       //追加したものを後ほど削除する事で、移動とする。
       const file         = DriveApp.getFileById(spreadsheetId);
       const folder       = DriveApp.getFolderById(folderId);
       const sourceFolder = DriveApp.getFolderById(sourceFolderId);
       
       file.moveTo(folder);
       
       
       //removeFileは廃止されたので、リライトしました。
       //folder.addFile(file);
       //sourceFolder.removeFile(file);
       
     }//if
   }//for_j
 }//for_i
}//end

removeFile()が、廃止されたみたいです。今までは、addFile()して、removeFile()をするしかなかったのですが、moveTo()が新しく出来たみたいです。

removeTo()は、setTrashed()に置き換わったようです。

フォルダ内の全てのファイルの名前を一部だけ置換するスクリプト

2020年8月に転職しました。前職では、外国人の在留資格などを扱う仕事だったため、スタッフ一人ごとにドライブのフォルダを作成し、パスポートや在留資格のコピー等をスキャンしたデータを格納していました。上記のような子フォルダや孫フォルダにアクセスして、書き出したり移動したいといった需要がありました。

転職先の実務では、凡ミスで全てのファイルに、2020_1101 と誤って付けてしまったファイル名を、40ファイルぐらい一括で2020_1107に置換したいというケースがありました。活用事例をアウトプットしておこうと思います。

function renameFiles() {
 const folder = DriveApp.getFolderById('*****************');
 const files  = folder.getFiles();
 
 console.log(folder.getName());
 console.log(files);
 
 
 while (files.hasNext()) {
   const file    = files.next();
   const fileId  = file.getId();
   
   //全ファイルの名前を一部分だけ置換したい
   //ここでは、 2020_1101 と誤ってつけてしまったファイル名を、 2020_1107 に全て置換する。
   
   const originalName = file.getName();
   const newName      = originalName.replace('2020_1101','2020_1107');
   
   //newNameで置換する
   file.setName(newName);
   console.log(newName);
   
 }//while
}//end

もし、フォルダの中の、条件を満たす一部のファイルの場合だけ置換する場合は、includesを使うとGoodです。

//ファイル名に、2020_1101を含むファイルのみ、置換する。
const originalName = file.getName();
if(originalName.includes('2020_1101') === true){
    const newName      = originalName.replace('2020_1101','2020_1107');
    file.setName(newName);
}

スタッフ別のファイルの作成は、こちらの記事で解説しています。

連番フォルダの作り方は、こちら

スタッフのIDや名前等を入れた上で、複数フォルダを作成する場合


この記事が気に入ったらサポートをしてみませんか?