基于此post,我正在研究一个概念证明,以通过Google表单捕获项目请求,通过电子邮件发送以供批准,并将批准结果发回到Google工作表的相应行中。使用时间戳作为键从数组中搜索该行。
我面临2个挑战:首先,阵列中的时间戳采用不同的格式,有时相差1秒。我通过调整格式以使其与数组值匹配来进行了调整,如果第一次时间戳搜索失败,则运行第二次搜索。我希望这是万无一失的,但请告诉我是否有更好的方法。我不知道为什么有时会有1秒的差异。
我被困在第二个挑战:我无法成功搜索数组中的时间戳记。 indexOf()始终返回值-1。
非常感谢您的帮助。如果需要,请详细说明,我是新手。
这是我的代码:
function sendEmail(e) {
// Response columns: Timestamp Requester Email Item Cost
var email = e.namedValues["Requester Email"];
var item = e.namedValues["Item"];
var cost = e.namedValues["Cost"];
var timestamp = e.namedValues["Timestamp"];
var url = ScriptApp.getService().getUrl();
// Enhancement: include timestamp to coordinate response
var options = '?approval=%APPROVE%×tamp=%TIMESTAMP%&reply=%EMAIL%'
.replace("%TIMESTAMP%",encodeURIComponent(e.namedValues["Timestamp"]))
.replace("%EMAIL%",e.namedValues["Requester Email"])
var approve = url+options.replace("%APPROVE%","Approved");
var reject = url+options.replace("%APPROVE%","Rejected");
var html = "<body>"+
"<h2>Please review</h2><br />"+
"Request from: " + email + "<br />"+
"For: "+item +", at a cost of: $" + cost + "<br /><br />"+
"<a href="+ approve +">Approve</a><br />"+
"<a href="+ reject +">Reject</a><br />"+
"</body>";
MailApp.sendEmail(Session.getEffectiveUser().getEmail(),
"Approval Request",
"Requires html",
{htmlBody: html});
}
function doGet(e) {
var answer = (e.parameter.approval === 'Approved') ? 'Buy it!' : 'Not this time, Keep saving';
var timestamp = e.parameter.timestamp;
var newtimestamp = Utilities.formatDate(new Date(timestamp), "GMT+8", "EEE MMM dd yyyy HH:mm:ss 'GMT+0800 (SGT)'"); //reformat timestamp to match the ones in the data array
var approvalCol = 5;
MailApp.sendEmail(e.parameter.reply, "Purchase Request",
"Your manager said: "+ answer);
// Update approval status back to the sheet
var wsID = "<myworksheetID>";
var sheet = SpreadsheetApp.openById(wsID).getSheetByName("Requests");
var data = sheet.getDataRange().getValues();
var oneColArray = new Array();
for(i=0;i<data.length;++i){
oneColArray.push(data[i][0]); // taking index 0 means I'll get column A of each row and put it in the new array
}
var row = oneColArray.indexOf(newtimestamp);
Logger.log("\ntimestamp: " + timestamp + "\n\n" + "newtimestamp: " + newtimestamp + "\n\n" + "oneColArray: \n" + oneColArray);
if (row < 0) { //not found
//Lower timestamp by 1 second. Sometimes there is a 1-second difference than the one in the array. I don't know why
var dateString = Utilities.formatDate(new Date(timestamp), "GMT+8",'EEE, d MMM yyyy HH:mm:ss');
var date = new Date(dateString);
var revisedtimestamp = new Date((date.getTime() - (1/(24*60*60)*1000)));
// now search again using the adjusted timestamp
var row = oneColArray.indexOf(revisedtimestamp);
if (row < 0) {
Logger.log("\ntimestamp: " + timestamp + "\n\n" + "newtimestamp: " + newtimestamp + "\n\n" + "oneColArray: \n" + oneColArray + "\n\n" + "revisedtimestamp: " + revisedtimestamp);
throw new Error ("Request not found in list.");
} else {
sheet.getRange(row + 1, approvalCol).setValue(e.parameter.approval);
}
} else {
sheet.getRange(row + 1, approvalCol).setValue(e.parameter.approval);
}
}
我基于此post找到了解决方案。
我更改了此行:
var row = oneColArray.indexOf(newtimestamp);
以此将数组转换为字符串,并且indexOf()返回找到时间戳第一次出现的起点。根据返回值,我只计算了工作表中的哪一行:
var row = oneColArray.join().indexOf(newtimestamp);
我更喜欢的另一种变化是遍历数据数组的timestamp列,在每个循环中,在执行indexOf()之前将值转换为字符串。我只需要在[i]上加1即可在工作表中获得实际的行。
for (var i = 0; i < data.length; ++i) {
var row = data[i][0].toString().indexOf(newtimestamp);
if (row > -1) {
var a = i;
break;
}
}