-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAutoShare.gs
More file actions
130 lines (118 loc) · 5.71 KB
/
AutoShare.gs
File metadata and controls
130 lines (118 loc) · 5.71 KB
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
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
/**
* 「帙雲」03 - 自動共用、收集位址
*
* 功用:將「04_已發還課業」中每位學生的專屬文件夾共用給學生,
* 並將文件夾位址記錄至「自動共用、收集位址」試算表的 C 欄,
* 方便批量分發給學生。
*
* 方法:在試算表中手動輸入學號(A 欄)及學生姓名(B 欄),
* 然後手動執行 shareAllClasses() 或針對特定班別執行 shareFoldersForClass()。
*
* 觸發器:不設觸發器,手動執行。
*
* 試算表格式(每個分頁對應一個班別):
* A1=學號, B1=姓名, C1=文件夾位址
* A2 起:實際學號, B2 起:實際姓名, C2 起(自動填入):文件夾 URL
*
* 注意:ROOT_FOLDER_ID、SCHOOL_EMAIL_DOMAIN、getConfig() 及 getOrCreateFolder()
* 定義於 Shared.gs,此處直接使用。
*/
// ─────────────────────────────────────────────────────────────────────────────
// 主函數
// ─────────────────────────────────────────────────────────────────────────────
/**
* 針對試算表中所有班別,共用學生專屬文件夾並收集位址。
* 試算表中每個分頁(Sheet)對應一個班別,分頁名稱即班別名稱(如 1C)。
*/
function shareAllClasses() {
try {
const config = getConfig();
const spreadsheet = SpreadsheetApp.openById(config.SHARE_SHEET_ID);
const returnedFolder = DriveApp.getFolderById(config.RETURNED_FOLDER_ID);
// 取得「04_已發還課業」下所有班別文件夾
const classFolderIter = returnedFolder.getFolders();
while (classFolderIter.hasNext()) {
const classFolder = classFolderIter.next();
const classKey = classFolder.getName().replace(/【|】/g, ''); // 去除【】
Logger.log('處理班別:' + classKey);
try {
shareFoldersForClass(classKey, classFolder, spreadsheet);
} catch (e) {
logError('shareAllClasses', '處理班別失敗:' + classKey, e.message);
}
}
logInfo('shareAllClasses', '自動共用完成。');
} catch (e) {
logError('shareAllClasses', e.message);
throw e;
}
}
/**
* 針對特定班別,共用學生專屬文件夾並收集位址。
*
* @param {string} className 班別名稱,如 "1C"
* @param {GoogleAppsScript.Drive.Folder} [classFolderOverride] 可選,直接傳入班別文件夾
* @param {GoogleAppsScript.Spreadsheet.Spreadsheet} [spreadsheetOverride] 可選,直接傳入試算表
*/
function shareFoldersForClass(className, classFolderOverride, spreadsheetOverride) {
const config = getConfig();
const spreadsheet = spreadsheetOverride || SpreadsheetApp.openById(config.SHARE_SHEET_ID);
const returnedFolder = DriveApp.getFolderById(config.RETURNED_FOLDER_ID);
// 找到對應的班別文件夾(名稱格式為「【1C】」)
let classFolder = classFolderOverride;
if (!classFolder) {
const iter = returnedFolder.getFoldersByName('【' + className + '】');
if (!iter.hasNext()) {
throw new Error('找不到班別文件夾:【' + className + '】');
}
classFolder = iter.next();
}
// 取得或建立試算表分頁
let sheet = spreadsheet.getSheetByName(className);
if (!sheet) {
sheet = spreadsheet.insertSheet(className);
sheet.getRange('A1:C1').setValues([['學號', '姓名', '文件夾位址']]);
sheet.getRange('A1:C1').setFontWeight('bold');
}
// 獲取學號及姓名(A2:B 往下)
const lastRow = sheet.getLastRow();
if (lastRow < 2) {
Logger.log('班別 ' + className + ' 的試算表中尚未輸入學生資料,跳過。');
return;
}
const values = sheet.getRange('A2:B' + lastRow).getValues();
// 建立姓名→文件夾映射
const folderMap = {};
const studentFolderIter = classFolder.getFolders();
while (studentFolderIter.hasNext()) {
const folder = studentFolderIter.next();
const match = folder.getName().match(/【(.*?)】/);
if (match) folderMap[match[1]] = folder;
}
// 共用並填入 URL
// 使用原始 values 陣列的索引 (valueIndex),使試算表列號 (valueIndex + 2) 始終正確,
// 不受空白列影響(空白列直接 return 跳過,但不佔用 valueIndex)。
values.forEach(function(student, valueIndex) {
if (!student[0] || !student[1]) return; // 跳過空列
const studentId = student[0];
const studentName = student[1];
const domain = PropertiesService.getScriptProperties()
.getProperty('SCHOOL_EMAIL_DOMAIN') || SCHOOL_EMAIL_DOMAIN;
const email = studentId + '@' + domain;
const folder = folderMap[studentName];
if (folder) {
try {
folder.addEditor(email);
sheet.getRange(valueIndex + 2, 3).setValue(folder.getUrl());
Logger.log('已共用文件夾給 ' + studentName + ' (' + email + ')');
} catch (e) {
logError('shareFoldersForClass', '共用失敗:' + studentName, e.message);
}
} else {
logWarn('shareFoldersForClass', '找不到學生文件夾:' + studentName);
}
});
}
// ─────────────────────────────────────────────────────────────────────────────
// 輔助函數
// ─────────────────────────────────────────────────────────────────────────────