教师缩放考勤工具
Teacher Zoom Attendance Tool
我是一名教师,我设计了一种工具,用于根据 Zoom 使用数据(我们生活的日子!)记录出勤率
Zoom 提供您可以复制和粘贴并保持格式为 table 的报告。像这样:
Luke Name Name
lr@email.com
09/10/2020 08:22:03 AM 09/10/2020 08:33:36 AM 12
Barbara Name Name
bar@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:57 AM 10
Joaquin Name Name Name
joa@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:59 AM 10
Rafaella Name Name
raf@email.com
09/10/2020 08:22:18 AM 09/10/2020 08:31:55 AM 10
Andrea Name Name
and@email.com
09/10/2020 08:22:19 AM 09/10/2020 08:32:14 AM 10
Sara Name Name Name
sar@email.com
09/10/2020 08:22:20 AM 09/10/2020 08:31:56 AM 10
如果将其发布到文本编辑器或 Google Sheet 中,它会正确地格式化为行和列。
我的代码现在获取那么长的信息字符串并删除任何不是电子邮件的内容,然后根据 class 列表检查电子邮件以查看谁不在。我现在要做的是检查迟到的学生。理想情况下,用户将输入字符串和时间 class 开始,它会显示缺席学生和单独的迟到学生。
我认为我无法弄清楚的部分是用户如何将信息复制粘贴到提示或 html 文本区域中,然后将其正确写入行和列以便我可以操作数据.
代码:
//this function copies the info to a spreadsheet and sets formulas in order to find just emails and check them against a student list
function checkAttendance() {
var ss = SpreadsheetApp
var sheet = ss.getActiveSheet();
var response = SpreadsheetApp.getUi().prompt("Student Attendance", "Paste emails of students who attended.", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(response.getSelectedButton() == SpreadsheetApp.getUi().Button.CANCEL) {return}
var responseText = response.getResponseText();
var splitText = responseText.split(" ");
var atHandle = SpreadsheetApp.getActive().getSheetByName("Attendance Handling");
atHandle.getRange(2, 1, 200, 100).clear();
atHandle.getRange(2, 3).setFormula("=FILTER(B2:B, ISNA(MATCH(B2:B, A2:A, 0)))");
var colNum = getColNum2("Student Email");
var rows = sheet.getLastRow();
sheet.getRange(2, colNum, rows-1, 1).copyTo(atHandle.getRange(2, 2, rows, 1));
atHandle.getRange(2, 1).setFormula('=TRANSPOSE(SPLIT(E2, " "))');
atHandle.getRange(2, 4).setFormula('=FILTER(A2:A, ISNA(MATCH(A2:A, B2:B, 0)))')
atHandle.getRange(2, 5).setValue(responseText);
atHandle.getRange(2, 6).setFormula('=if(AND(IFERROR(SEARCH("@", D2), "") <> "", IFERROR(SEARCH("(", D2), "") = ""), D2, "")');
SpreadsheetApp.getActive().getSheetByName("Attendance Handling").getRange(2, 6).copyTo(SpreadsheetApp.getActive().getSheetByName("Attendance Handling").getRange(2, 6, 200, 1));
atHandle.getRange(2, 7).setFormula('=FILTER(F2:F, F2:F <> "")');
showAttendance()
}
function showAttendance() {
var atHandle = SpreadsheetApp.getActive().getSheetByName("Attendance Handling");
var rows1 = getLastRow(3);
var rows2 = getLastRow(7)
var absent = atHandle.getRange(2, 3, rows1-1, 1).getValues().join("\n");
var present = atHandle.getRange(2, 7, rows2-1, 1).getValues().join("\n");
var t = HtmlService.createTemplateFromFile('attendance'); // Modified
t.Absent = absent
t.Present = present
html = t.evaluate().setWidth(600).setHeight(345); // Added
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'Class Attendance');
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
//style removed for space
</head>
<body>
<form>
<div>
Absent (in student list but not in pasted values):
<br>
<textarea id="tofield" name="tofield" rows="9" cols="60"><?!= Absent ?></textarea>
<br>
Guests (present in pasted values but not in student list):
<br>
<textarea id="tofield" name="tofield" rows="9" cols="60"><?!= Present ?></textarea>
<br>
<p>
</p>
</form>
Note: this information is not saved. Please use or copy and paste this information as needed beforing closing.
<p>
<button id="btn" style="margin-left: 8px; font-size: 15px; padding: 5px" onclick='google.script.host.close();' class="sbtn btn btn-secondary btn-c">Close</button>
</p>
</body>
</html>
您可以根据解析出的时间构建一个新的 Date
对象并进行比较。如果您可以获得 dat 的字符串 representaiotn,则可以将其传递给 Date
diruectrly
的构造函数
new Date('December 17, 1995 03:24:00');
获得日期后,您可以使用运算符比较它们,并确定学生是否迟到。
function isLate(classStart) {
var dateStr = /* get the cell value */
var studentArrvial = Date.parse(dateStr)
return studentArrival - dateStr > 0
}
您需要使用 google.script.run.doSomething(data)
之类的东西将值从 client-side 传递到服务器端代码,其中 doSomething
是服务器端函数,data
是a 保存要传递给客户端的值/对象的变量。
注意:对于哪些 values/object 类型可以传递给 server-side 有一些限制,即不能传递日期对象,但您可以将字符串添加到对应的毫秒数。
以下代码将示例数据输入转换为二维数组,可以使用 setValues(values)
.
传递给 sheet
var data = `Luke Name Name
lr@email.com
09/10/2020 08:22:03 AM 09/10/2020 08:33:36 AM 12
Barbara Name Name
bar@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:57 AM 10
Joaquin Name Name Name
joa@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:59 AM 10
Rafaella Name Name
raf@email.com
09/10/2020 08:22:18 AM 09/10/2020 08:31:55 AM 10
Andrea Name Name
and@email.com
09/10/2020 08:22:19 AM 09/10/2020 08:32:14 AM 10
Sara Name Name Name
sar@email.com
09/10/2020 08:22:20 AM 09/10/2020 08:31:56 AM 10`;
const arr = data.split('\n');
const matrix = [];
for(let i = 0; i < arr.length;i = i + 3){
var row = [arr[i],arr[i+1],
new Date(arr[i+2].slice(0,22)),
new Date(arr[i+2].slice(24,46)),
arr[i+2].slice(48)]
matrix.push(row);
}
console.info(matrix);
我建议你在服务器端使用上面的方法,如前所述,因为 Date 对象不能从 client-side 传递到 sever-side,只要确保 Apps 脚本, Spreadsheet 和 Zoom 使用相同的时区,否则你将不得不改进它以适当地处理时区差异。
资源
我是一名教师,我设计了一种工具,用于根据 Zoom 使用数据(我们生活的日子!)记录出勤率
Zoom 提供您可以复制和粘贴并保持格式为 table 的报告。像这样:
Luke Name Name
lr@email.com
09/10/2020 08:22:03 AM 09/10/2020 08:33:36 AM 12
Barbara Name Name
bar@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:57 AM 10
Joaquin Name Name Name
joa@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:59 AM 10
Rafaella Name Name
raf@email.com
09/10/2020 08:22:18 AM 09/10/2020 08:31:55 AM 10
Andrea Name Name
and@email.com
09/10/2020 08:22:19 AM 09/10/2020 08:32:14 AM 10
Sara Name Name Name
sar@email.com
09/10/2020 08:22:20 AM 09/10/2020 08:31:56 AM 10
如果将其发布到文本编辑器或 Google Sheet 中,它会正确地格式化为行和列。
我的代码现在获取那么长的信息字符串并删除任何不是电子邮件的内容,然后根据 class 列表检查电子邮件以查看谁不在。我现在要做的是检查迟到的学生。理想情况下,用户将输入字符串和时间 class 开始,它会显示缺席学生和单独的迟到学生。
我认为我无法弄清楚的部分是用户如何将信息复制粘贴到提示或 html 文本区域中,然后将其正确写入行和列以便我可以操作数据.
代码:
//this function copies the info to a spreadsheet and sets formulas in order to find just emails and check them against a student list
function checkAttendance() {
var ss = SpreadsheetApp
var sheet = ss.getActiveSheet();
var response = SpreadsheetApp.getUi().prompt("Student Attendance", "Paste emails of students who attended.", SpreadsheetApp.getUi().ButtonSet.OK_CANCEL);
if(response.getSelectedButton() == SpreadsheetApp.getUi().Button.CANCEL) {return}
var responseText = response.getResponseText();
var splitText = responseText.split(" ");
var atHandle = SpreadsheetApp.getActive().getSheetByName("Attendance Handling");
atHandle.getRange(2, 1, 200, 100).clear();
atHandle.getRange(2, 3).setFormula("=FILTER(B2:B, ISNA(MATCH(B2:B, A2:A, 0)))");
var colNum = getColNum2("Student Email");
var rows = sheet.getLastRow();
sheet.getRange(2, colNum, rows-1, 1).copyTo(atHandle.getRange(2, 2, rows, 1));
atHandle.getRange(2, 1).setFormula('=TRANSPOSE(SPLIT(E2, " "))');
atHandle.getRange(2, 4).setFormula('=FILTER(A2:A, ISNA(MATCH(A2:A, B2:B, 0)))')
atHandle.getRange(2, 5).setValue(responseText);
atHandle.getRange(2, 6).setFormula('=if(AND(IFERROR(SEARCH("@", D2), "") <> "", IFERROR(SEARCH("(", D2), "") = ""), D2, "")');
SpreadsheetApp.getActive().getSheetByName("Attendance Handling").getRange(2, 6).copyTo(SpreadsheetApp.getActive().getSheetByName("Attendance Handling").getRange(2, 6, 200, 1));
atHandle.getRange(2, 7).setFormula('=FILTER(F2:F, F2:F <> "")');
showAttendance()
}
function showAttendance() {
var atHandle = SpreadsheetApp.getActive().getSheetByName("Attendance Handling");
var rows1 = getLastRow(3);
var rows2 = getLastRow(7)
var absent = atHandle.getRange(2, 3, rows1-1, 1).getValues().join("\n");
var present = atHandle.getRange(2, 7, rows2-1, 1).getValues().join("\n");
var t = HtmlService.createTemplateFromFile('attendance'); // Modified
t.Absent = absent
t.Present = present
html = t.evaluate().setWidth(600).setHeight(345); // Added
SpreadsheetApp.getUi() // Or DocumentApp or FormApp.
.showModalDialog(html, 'Class Attendance');
}
<!DOCTYPE html>
<html>
<head>
<base target="_top">
//style removed for space
</head>
<body>
<form>
<div>
Absent (in student list but not in pasted values):
<br>
<textarea id="tofield" name="tofield" rows="9" cols="60"><?!= Absent ?></textarea>
<br>
Guests (present in pasted values but not in student list):
<br>
<textarea id="tofield" name="tofield" rows="9" cols="60"><?!= Present ?></textarea>
<br>
<p>
</p>
</form>
Note: this information is not saved. Please use or copy and paste this information as needed beforing closing.
<p>
<button id="btn" style="margin-left: 8px; font-size: 15px; padding: 5px" onclick='google.script.host.close();' class="sbtn btn btn-secondary btn-c">Close</button>
</p>
</body>
</html>
您可以根据解析出的时间构建一个新的 Date
对象并进行比较。如果您可以获得 dat 的字符串 representaiotn,则可以将其传递给 Date
diruectrly
new Date('December 17, 1995 03:24:00');
获得日期后,您可以使用运算符比较它们,并确定学生是否迟到。
function isLate(classStart) {
var dateStr = /* get the cell value */
var studentArrvial = Date.parse(dateStr)
return studentArrival - dateStr > 0
}
您需要使用 google.script.run.doSomething(data)
之类的东西将值从 client-side 传递到服务器端代码,其中 doSomething
是服务器端函数,data
是a 保存要传递给客户端的值/对象的变量。
注意:对于哪些 values/object 类型可以传递给 server-side 有一些限制,即不能传递日期对象,但您可以将字符串添加到对应的毫秒数。
以下代码将示例数据输入转换为二维数组,可以使用 setValues(values)
.
var data = `Luke Name Name
lr@email.com
09/10/2020 08:22:03 AM 09/10/2020 08:33:36 AM 12
Barbara Name Name
bar@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:57 AM 10
Joaquin Name Name Name
joa@email.com
09/10/2020 08:22:12 AM 09/10/2020 08:31:59 AM 10
Rafaella Name Name
raf@email.com
09/10/2020 08:22:18 AM 09/10/2020 08:31:55 AM 10
Andrea Name Name
and@email.com
09/10/2020 08:22:19 AM 09/10/2020 08:32:14 AM 10
Sara Name Name Name
sar@email.com
09/10/2020 08:22:20 AM 09/10/2020 08:31:56 AM 10`;
const arr = data.split('\n');
const matrix = [];
for(let i = 0; i < arr.length;i = i + 3){
var row = [arr[i],arr[i+1],
new Date(arr[i+2].slice(0,22)),
new Date(arr[i+2].slice(24,46)),
arr[i+2].slice(48)]
matrix.push(row);
}
console.info(matrix);
我建议你在服务器端使用上面的方法,如前所述,因为 Date 对象不能从 client-side 传递到 sever-side,只要确保 Apps 脚本, Spreadsheet 和 Zoom 使用相同的时区,否则你将不得不改进它以适当地处理时区差异。
资源