Gg / Google Drive 移動副本文件到特定資料夾 4

Gg / Google Drive 移動副本文件到特定資料夾 3」說明主程式

接下來說明子程式

處理G欄的子程式 copyFileToFolder(n, n1, n2, n3, n4)

#18-33

事先設定2個陣列來取得傳入的 rSub對應的資料夾ID

利用replace函數搭配正則表達式將空格取代為空字串

原本有判斷繳交作業科目的資料夾內是否有相同名稱的資料夾

但是後來省略了,因為在主程式已經判斷是否已經執行過程式

而且Google Deive也會自動更名,所以也沒必要處理

#48-50

建立上傳者的個別作業資料夾,移動到對應的科目資料夾內

#52-64

複製檔案到上傳者的個別作業資料夾

由於主程式傳來的是陣列

所以透過陣列長度來設定迴圈,逐一建立副本之後再移動到資料夾內

由於取得的網址字串會有空格,所以在#56先用toString()確保是字串型態,trim()去除字串前後的空格

再利用replace函數搭配正則表達式將字串內的空格取代為空字串

#65-68

建立程式的回傳值

由於要同時回傳2個值,所以建立為陣列

第一筆為”good”表示順利執行,配合主程式在工作表的I欄寫入”◎”

不過因為沒有除錯機制,程式出錯就是中止…

第二筆為新建立的上傳者個別作業資料夾ID

配合主程式寫入工作表的J欄

 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)

跟copyFileToFolder()最大的差異是第5個參數

在正常的情況之下,這裡會收到上傳者提供的雲端資料夾連結

不過有可能也會收到檔案連結

所以在#10-18先利用try catch語法來進行錯誤處理

如果#12-13程式出錯,可能原因為

  • 分享的不是雲端資料夾連結,所以#12在第一次分割的時候就會出錯,因為如果是檔案連結,網址不會有”https://drive.google.com/drive/folders/”,所以會得到一個只有原本字串的陣列,所以陣列內也就不會有第2筆資料,再進行分割的時候程式就會出錯
  • 分享的雲端資料夾沒有設定「共用」,因此#13就會因為沒有權限而報錯

當程式出錯被catch捕捉到,就會寫入error內(可以自己決定這個參數名稱)

#15-16

設定寫入的結構

第一筆是”bad”,表示出錯

第二筆是錯誤訊息

配合主程式將錯誤訊息寫入K欄

#20-38

跟copyFileToFolder()一樣

#40-54

參考#65-81的程式

這個程式是透過while迴圈設計成遞迴程式

也就是自己呼叫自己直到設定的中止條件

程式的#41-52還是依照流程設計

但是到了最後要遍歷下一層資料夾時呼叫copy()

#41

透過getFiles()取得來源雲端資料夾內的所有檔案

#42-46

利用while迴圈逐一將檔案建立副本,再移動到新的資料夾內

#49-54

處理第一層資料夾內的資料夾

將資料夾傳入copy()處理之中的子資料夾跟檔案

#56-60

設定回傳資料

這裡也跟copyFileToFolder()一樣

但是這邊的”good” “bad”是有意義的

 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);
  }
}