Google Apps脚本在电子表格中双重删除行
Google Apps Script double deleting rows in spreadsheet
function onEdit() {
var openRequests = SpreadsheetApp.getActive().getSheetByName('Open Requests');
var lastRowOpen = openRequests.getLastRow();
var closedRequests = SpreadsheetApp.getActive().getSheetByName('Closed Requests');
var lastRowClose = closedRequests.getLastRow();
var closed = openRequests.getRange(2,8,lastRowOpen,1).getValues();
for (var i = 0; i < lastRowOpen; i++)
{
if (closed[i][0].toString() == 'Yes')
{
var line = i+2;
if (closedRequests.getLastRow() == 1)
{
openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(2,1,1,9));
closedRequests.getRange(2,9,1,1).setValue(new Date());
openRequests.deleteRow(line);
}
else
{
openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(lastRowClose+1,1,1,9));
closedRequests.getRange(lastRowClose+1,9,1,1).setValue(new Date());
openRequests.deleteRow(line);
}
}
}
}
我设置了一个触发器来运行onEdit。它所做的是检查一列Closed
看它是否写着Yes
。Closed
列有一个数据验证下拉菜单,值为Yes
。
所以当我点击下拉菜单并选择Yes
时,它应该将整行复制到另一个名为Closed Requests
的工作表中,然后从名为Open Requests
的电子表格中删除该行。
我遇到的问题是,大约50%的时间,它删除了我选择Yes
的行,但它也删除了它下面的行(大约50%的时间,当这种情况发生时,只有一些时候第二个删除的行出现在Closed Requests
中,其他时间整个行只是永远消失,除非我撤消)。
据我所知,deleteRow()
函数删除整行并将其下方的所有行上移一行以填充空白。所以要删除的那一行下面的那一行被移到了同一行,也被删除了。我不知道为什么这个函数被调用了两次。
我试着添加一些延迟,但它似乎不工作。
function onEdit(e) {
var eRange = e.source.getActiveRange();
var openRequests = SpreadsheetApp.getActive().getSheetByName('Open Requests');
var closedRequests = SpreadsheetApp.getActive().getSheetByName('Closed Requests');
var nextRowClose = (closedRequests.getLastRow()?closedRequests.getLastRow()+1:2);
if(eRange.getSheet().getName()=="Open Requests" && eRange.getColumn()==8 && eRange.getValue()=="Yes") {
openRequests.getRange(eRange.getRow(), 1, 1, 9)
.copyTo(closedRequests.getRange(nextRowClose, 1));
closedRequests.getRange(nextRowClose, 9).setValue(new Date());
openRequests.deleteRow(eRange.getRow());
}
}
可以尝试像我提到的那样向后迭代。在删除后抛出SpreadsheetApp.flush()
也可能有所帮助。
@Jack,我有一个和你类似的用例。我的代码是BryanP讨论的反向代码。我的代码或多或少在这里:"批量删除状态= 'Done'的任务项"。这是因为我在一批中删除它们,我使用向后方法,即删除具有较高行号的行不会干扰具有较低行号的任何行的行号。
但是你不是在批处理模式下删除行,所以也许向后不应该有什么区别(也许除非两个用户同时使用表和删除?)
所以我想试试你的代码。我将您的代码插入到我的电子表格上已经存在的onedit()函数中(该函数用于在一段时间不活动后将行涂成红色,并在实际参加任务后放入时间戳)。
然后为了测试,我使用了一个已经有50行/任务的电子表格副本。我手动填写一行中所需的单元格,并通过下拉菜单从单元格中选择Done(我更改了代码以期望"Done"而不是"Yes")。我重复了20行。
结果:你的代码成功了,正如你所期望的那样,每一次都成功了。没有双重删除,总是复制数据。它为我工作,没有引入延迟和SpreadsheetApp.flush()。
恐怕我没有可靠的建议。顺便提一下,我提到了电子表格本身没有正确刷新的已知错误,因此没有显示删除的行;这可以通过在出现此错误时手动刷新电子表格来检查。(然而,这个错误的迹象似乎在逻辑上不符合你的报告关于两个连续的行重复复制。)线程锁定?听起来像是线程锁问题。试一试:
function onEdit() {
// ****** add lock code
var lock = LockService.getPublicLock();
var hasMutex = lock.tryLock(100);
if(hasMutex==false) {
return;
}
// *** end
var openRequests = SpreadsheetApp.getActive().getSheetByName('Open Requests');
var lastRowOpen = openRequests.getLastRow();
var closedRequests = SpreadsheetApp.getActive().getSheetByName('Closed Requests');
var lastRowClose = closedRequests.getLastRow();
var closed = openRequests.getRange(2,8,lastRowOpen,1).getValues();
for (var i = 0; i < lastRowOpen; i++)
{
if (closed[i][0].toString() == 'Yes')
{
var line = i+2;
if (closedRequests.getLastRow() == 1)
{
openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(2,1,1,9));
closedRequests.getRange(2,9,1,1).setValue(new Date());
openRequests.deleteRow(line);
}
else
{
openRequests.getRange(line,1,1,9).copyTo(closedRequests.getRange(lastRowClose+1,1,1,9));
closedRequests.getRange(lastRowClose+1,9,1,1).setValue(new Date());
openRequests.deleteRow(line);
}
}
}
// ****** add lock code
lock.releaseLock();
// *** end
}
问题:
1)当时有多少人在使用电子表格。
- 如何使用谷歌应用程序脚本将3个谷歌电子表格中的特定行复制到另一个电子表格中
- 谷歌电子表格-删除范围保护时出错
- 谷歌脚本在5分钟后删除电子表格行
- 从web服务中检索10000行并插入到OWC11电子表格中
- 从 Google 表格中删除行
- 意外的删除行为谷歌电子表格应用程序
- Javascript:如果列包含任何日期,则在 google 电子表格中移动行 (1/2/2015)
- 如何使用谷歌脚本在电子表格中插入多行
- 谷歌电子表格脚本为包含某个单词的行着色,并自动将该行移动到另一张工作表
- HtmlService表不支持电子表格中的换行符和超链接
- 如何使用URL在特定单元格/行打开电子表格
- 获取匹配值的电子表格行
- 基于换行符的谷歌电子表格分割
- 在Google电子表格中的几行中迭代一个函数
- 谷歌可视化查询&表格-没有返回正确的行简单的电子表格
- Google Apps脚本-在电子表格中找到列的最后一个空行
- 谷歌电子表格:插入行并复制隐藏的内容
- Oracle APEX |如何使用JavaScript从表格中删除行
- Google电子表格脚本-迭代活动选择的行,但所有列
- Google Apps脚本在电子表格中双重删除行