延續「Gg / Google Drive 移動副本文件到特定資料夾 1」
處理如何把上傳的檔案分門別類放在各自的資料夾內
這當然就需要用Google Apps Script來達成,為了避免動到表單資料
所以將資料複製到另一個工作表,並增加會用到的欄位
A至H欄是原本的表單資料
I欄是紀錄是否已經處理過,避免重覆複製檔案
J欄是新的個別作業資料夾的連結
K欄是用來記錄如果錯誤時的訊息
回過頭來說程式的構想
如果透過表單上傳,G欄會是每一個檔案的連結路徑
如果直接提供雲端資料夾,H欄會是一個雲端資料夾的連結路徑
主程式要先處理表單上的資料
再透過兩個子程式處理G欄或H欄的連結
主程式 getDatafromSheet()
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 |
function getDatafromSheet() { //https://docs.google.com/spreadsheets/d/***************************************/ //113-修訂版學習扶助師資研習課程講師培訓課程-課後作業 (回覆) var ss = SpreadsheetApp.openById("***************************************"); var sOne = ss.getSheets()[2];//工作表-作業處理 //Logger.log(sOne.getName()); var r = sOne.getLastRow(); //var r = 3 //Logger.log(r); for (var i = 2; i <= r; i++) { //Logger.log(i); var checkDo = sOne.getRange(i, 9).getValue(); if (checkDo === "") { var rName = sOne.getRange(i, 3).getValue();//姓名 //Logger.log(rName); var rCity = sOne.getRange(i, 5).getValue();//服務縣市 //Logger.log(rCity); var rSub = sOne.getRange(i, 6).getValue();//繳交作業科目 //Logger.log(rSub); var rFiles = sOne.getRange(i, 7).getValue();//課後作業上傳 var rFilesArr = rFiles.toString().split(","); //Logger.log(rFilesArr.length); var rDriUrl = sOne.getRange(i, 8).getValue();//雲端資料夾網址 //Logger.log(rDriUrl); //var resultMoveFile = test(); //Logger.log(resultMoveFile); if (rFiles == "" && rDriUrl != "") { var reustMg = copyDriUrl(i, rName, rCity, rSub, rDriUrl); } else { var reustMg = copyFileToFolder(i, rName, rCity, rSub, rFilesArr); } //Logger.log(reustMg); if (reustMg[0] === "good") { sOne.getRange(i, 9).setValue("◎"); sOne.getRange(i, 10).setValue("https://drive.google.com/drive/folders/" + reustMg[1]); } else if (reustMg[0] === "bad") { sOne.getRange(i, 11).setValue(reustMg[1]); } //if reustMg } else { Logger.log("已執行過"); } // if checkDo } //for i } |
處理G欄的子程式 copyFileToFolder(n, n1, n2, n3, n4)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
//******************************************************************************************************************* // //n,序號 //n1,姓名 rName //n2,服務縣市 rCity //n3,繳交作業科目 rSub //n4,課後作業上傳 rFilesArr function copyFileToFolder(n, n1, n2, n3, n4) { //Logger.log(n1); //Logger.log(n2); //Logger.log(n3); //Logger.log(n4); //主資料夾 課後作業/表單上傳 //var mainFolder = DriveApp.getFolderById("10BOUbWUaVzPrxu1MbeXiDuAJmQ1tIGan"); var subName = n3;//繳交作業科目 //繳交作業科目的資料夾 var arr1 = ["國中國語文(繳交期限10/14)", "國小國語文(繳交期限10/14)", "國中英語文(繳交期限10/13)", "國小英語文(繳交期限10/6)", "國中數學(繳交期限10/13)", "國小數學(繳交期限10/13)-01-國小學生數學學習發展與實務", "國小數學(繳交期限10/13)-02-國小數學補救教學課程規劃", "共同課程二-國中(繳交期限10/31)", "共同課程二-國小(繳交期限10/18)"]; //對應繳交作業科目的資料夾的資料夾ID var arr2 = ["******************", "******************", "******************", "******************", "******************", "******************", "******************", "******************", "******************"]; //取得繳交作業科目在arr1的位置 var subIndex = arr1.indexOf(subName); //ogger.log(subIndex); //Logger.log(arr2[subIndex]); //透過arr1的相對位置取得arr2的對應值 var subId = arr2[subIndex];//繳交作業科目的資料夾 folderID var subFolder = DriveApp.getFolderById(subId); //判斷是否已經有相同名稱的資料夾在科目資料夾內 var folderName = n + n3 + "-" + n1; /* var folders = subFolder.getFolders(); while (folders.hasNext()) { folder = folders.next(); if (folder.getName() === folderName) { i=2; folder.setName(folderName +"-"+ i); i=i+1; break; }; }*/ var workFolder = DriveApp.createFolder(folderName); workFolder.moveTo(subFolder);//將學員的作業資料夾移動到對應的科目資料夾 var workFolderId = workFolder.getId(); //Logger.log(n4); //移動作業檔案 for (var r = 0; r < n4.length; r++) { //https://stackoverflow.com/questions/50051358/trim-and-clean-google-script //https://stackoverflow.com/questions/5964373/is-there-a-difference-between-s-g-and-s-g var dUrl = n4[r].toString().trim().replace(/\s(?=\s)/g, ''); //Logger.log(dUrl); var dId = dUrl.split("=")[1]; //Logger.log(dId); var fOne = DriveApp.getFileById(dId); var new_fOne = fOne.makeCopy(workFolder); } var msg = []; msg.push("good"); msg.push(workFolderId); return msg; } |
處理H欄的子程式 copyDriUrl(e, e1, e2, e3, e4)
#40-54
程式碼參考了#65-81的copy(fromFolder, toFolder)
因為Google Drive 無法直接透過程式複製整個資料夾
要先創建資料夾,再複製檔案
由於資料夾可能會有好幾層
這個程式先複製第一層的所有檔案到指定的資料夾
然後再尋找第一層是否有資料夾
如果有資料夾,就在指定的資料夾內創建相同名稱的資料夾
再把資料夾內的檔案複製到這個資料夾
遍歷到所有的資料夾跟檔案
這個設計概念在之前的VBA遍歷FTP內的所有資料夾跟檔案很類似
在程式內呼叫自己的遞迴程式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 |
//******************************************************************************************************************* // //e,序號 //e1,姓名 rName //e2,服務縣市 rCity //e3,繳交作業科目 rSub //e4,雲端資料夾網址 rDriUrl function copyDriUrl(e, e1, e2, e3, e4) { var msg = [];//記錄錯誤訊息 try { var fromFolderId = e4.toString().split("https://drive.google.com/drive/folders/")[1].split("?")[0]; var fromFolder = DriveApp.getFolderById(fromFolderId); } catch (error) { msg.push("bad"); msg.push(error); return msg; } var subName = e3;//繳交作業科目 //繳交作業科目的資料夾 var arr1 = ["國中國語文(繳交期限10/14)", "國小國語文(繳交期限10/14)", "國中英語文(繳交期限10/13)", "國小英語文(繳交期限10/6)", "國中數學(繳交期限10/13)", "國小數學(繳交期限10/13)-01-國小學生數學學習發展與實務", "國小數學(繳交期限10/13)-02-國小數學補救教學課程規劃", "共同課程二-國中(繳交期限10/31)", "共同課程二-國小(繳交期限10/18)"]; //對應繳交作業科目的資料夾的資料夾ID var arr2 = ["******************", "******************", "******************", "******************", "******************", "******************", "******************", "******************", "******************"]; //取得繳交作業科目在arr1的位置 var subIndex = arr1.indexOf(subName); //ogger.log(subIndex); //Logger.log(arr2[subIndex]); //透過arr1的相對位置取得arr2的對應值 var subId = arr2[subIndex];//繳交作業科目的資料夾 folderID var subFolder = DriveApp.getFolderById(subId); var folderName = e + e3 + "-" + e1; var workFolder = DriveApp.createFolder(folderName); workFolder.moveTo(subFolder);//將學員的作業資料夾移動到對應的科目資料夾 // copy files var fromFiles = fromFolder.getFiles(); while (fromFiles.hasNext()) { var fOne = fromFiles.next(); var newFile = fOne.makeCopy(workFolder); newFile.setName(fOne.getName()); } // copy folders var folders = fromFolder.getFolders(); while (folders.hasNext()) { var folder = folders.next(); var newFolder = workFolder.createFolder(folder.getName()); copy(folder, newFolder); } var workFolderId = workFolder.getId(); msg.push("good"); msg.push(workFolderId); return msg; } // //參考 https://gist.github.com/KenjiOhtsuka/d4432b6d80ad2b81ab7c965de2a8a00d // function copy(fromFolder, toFolder) { // copy files var files = fromFolder.getFiles(); while (files.hasNext()) { var file = files.next(); var newFile = file.makeCopy(toFolder); newFile.setName(file.getName()); } // copy folders var folders = fromFolder.getFolders(); while (folders.hasNext()) { var folder = folders.next(); var newFolder = toFolder.createFolder(folder.getName()); copy(folder, newFolder); } } |
接下來再來說明程式內容