function - 在谷歌表格中发送电子邮件后出现 onEdit 问题
问题描述
这是我在谷歌脚本中的代码:
function Send(){
Browser.msgBox("Send");
}
function myFunction() {
var sheet = SpreadsheetApp.getActiveSheet();
var startRow = 2;
var lr = sheet.getLastRow();
var dataRange = sheet.getRange(startRow, 1, lr-1, 6);
var data = dataRange.getValues();
for (var i = 0; i < data.length; i++) {
var row = data[i];
var name = row[0];
var emailAddress = row[1];
var date = row[2];
var city = row[3];
var status = row[6];
if (emailAddress.match('@') === null){
continue;
};
var subject = row[4];
var message = "Hey " + name + ", welcome in the team " + row[5];
MailApp.sendEmail(emailAddress, subject, message);
sheet.getRange(i+2,7).setValue("Sent");
}
}
直到这里一切正常。我希望当“已发送”出现在第 7 列时,将“已发送”所在的整行移动到另一个选项卡。
function onEdit(e) {
var ss = e.source;
var s = ss.getActiveSheet();
var r = e.range;
var actionCol = 7;
var nameCol = 7;
var rowIndex = r.getRowIndex();
var colIndex = r.getColumnIndex();
var colNumber = s.getLastColumn()-1;
if (e.value == "Sent" && colIndex == actionCol) {
var targetSheet = s.getRange(rowIndex, nameCol).getValue();
if (ss.getSheetByName("Welcome")) {
var targetSheet = ss.getSheetByName("Done");
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
var sourceRange = s.getRange(rowIndex, 1, 1, colNumber);
sourceRange.copyTo(targetRange);
s.deleteRow(rowIndex);
}
}
}
**如果我在第 7 列手动写“已发送”,则该行将移至另一张表。但是当我运行第一个函数并且“已发送”出现在该列中时,onEdit 函数不起作用。所以基本上这两个功能都可以工作,但不能同时使用。
有人知道解决这个问题吗?**
解决方案
问题:
- 您正在尝试
onEdit
通过脚本触发函数,但这不是触发器的工作方式。官方文档声明如下:
当
onEdit(e)
用户更改电子表格中任何单元格的值时,触发器会自动运行。
也就是说,onEdit
触发器仅由用户操作激活,而不是由脚本或公式激活。
您不需要单独的函数来检查该值是否为
Sent
,然后使用另一个函数删除该行。发送电子邮件后,您可以移动数据并删除行,所有这些都在同一个功能中。最后但同样重要的是,当迭代删除行时,我们会更改工作表的结构,因此数据输入与更新后的结构不匹配。为了缓解这个问题,我们可以将要删除的行的索引存储在一个数组中,然后使用该数组向后删除行。
解决方案:
假设您的代码单独工作,这也应该工作:
function myFunction() {
var ss = SpreadsheetApp.getActive();
var sheet = ss.getSheetByName("Welcome");
var targetSheet = ss.getSheetByName("Done");
var startRow = 2;
var lr = sheet.getLastRow();
var dataRange = sheet.getRange(startRow, 1, lr-1, 6);
var data = dataRange.getValues();
var colNumber = sheet.getLastColumn()-1;
var delRows = [];
for (var i = 0; i < data.length; i++) {
var row = data[i];
var name = row[0];
var emailAddress = row[1];
var date = row[2];
var city = row[3];
var status = row[6];
if (emailAddress.match('@') === null){
continue;
};
var subject = row[4];
var message = "Hey " + name + ", welcome in the team " + row[5];
MailApp.sendEmail(emailAddress, subject, message);
var targetRange = targetSheet.getRange(targetSheet.getLastRow()+1, 1, 1, colNumber);
var sourceRange = sheet.getRange(i+startRow, 1, 1, colNumber);
sourceRange.copyTo(targetRange);
delRows.push(i+startRow);
}
// delete rows in reverse order
delRows.reverse().forEach(ri=>{sheet.deleteRow(ri)});
}
您不再需要该onEdit
功能,因此可以将其删除。
推荐阅读
- javascript - 在recusion中使用辅助方法
- python - ModuleNotFoundError:当 pip 显示安装了 sklearn 时,没有名为“sklearn”的模块
- twitter-bootstrap - 如何使用 Bootstrap 使导航栏切换按钮/下拉菜单在“sm”屏幕尺寸下工作?
- jquery - JQuery 多步进度条:next_fs 问题
- java - 如何在其他类中显示来自 JTextField 的文本?
- java - 用 JFreeChart 实现蜘蛛图
- ios - 更改 iOS Xamarin 表单上的导航栏高度?
- java - @ResponseBody,不要尊重对象的构造函数
- postgresql - 橙色(数据挖掘)psycopg2 使用 postgresql 12.2 连接失败“不支持的前端协议”
- javascript - 一个属性值可以作为参数传递给另一个属性,其值是通过函数计算的吗?(在带有类的 Javascript ES6 中)