我目前正在处理一个脚本,该脚本应该从数据集中删除标记为“完成”或为空的行。我有一个工作循环,该操作会删除所有完成的行,但只删除每组空行的第一行。
我发现了多种解决方案,但是所有这些解决方案都增加了i
,因此需要跟踪已删除的行数,以便在删除下一行时匹配正确的行。
function sheetclear(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet");
var range = sheet.getDataRange();
var firstrow = 5;
var numrow = range.getNumRows()-firstrow;
var values = sheet.getRange(firstrow,1,numrow+1,8).getValues();
if(sheet.getRange("h3").getValue() == true){ //h3 acts as a trigger
for (i = parseInt(numrow)-1; i >= 0; i--){
var row = values[parseInt(i)]
if(row[7] == "done" || (row[1] == "" && values[(parseInt(i)+1)][1] != "")){
sheet.deleteRow((parseInt(i)+firstrow))
}
}
//Re-adding the deleted rows and formatting them
sheet.insertRowsAfter(sheet.getLastRow(),100-sheet.getLastRow());
sheet.getRange(firstrow,1,numrow+1,8).setBorder(false, true, false, true, true, false, "silver",SpreadsheetApp.BorderStyle.SOLID)
sheet.getRange("h3").setValue(false);
}
}
我是JavaScript的业余爱好者,所以(可能很明显)解决方案使我难以理解。我怀疑这与一次检查值有关,而不是在每次迭代后检查。
这里有人可以指出正确的道路吗?
答案 0 :(得分:0)
if(row[7] == "done" || (row[1] == "" && values[(parseInt(i)+1)][1] != ""))
在以下情况下,将上述条件评估为真:
因此,如果您有多个相邻的行且其值为空,则除一行外,将不满足任何条件。因此,它将仅删除一行。
请删除&&条件的第二部分,使其类似:
if(row[7] == "done" || (row[1] == ""))
答案 1 :(得分:0)
您正在向后循环,并将行值和行比较为 您的计数器变量的功能-这会使代码混乱。您 最终会删除错误的行。
我建议您通过以下方式修改代码:
function sheetclear(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet");
var range = sheet.getDataRange();
var firstrow = 1;
var numrow = range.getNumRows();
if(sheet.getRange("h3").getValue() == true){ //h3 acts as a trigger
for (var i = numrow-1; i >0; i--){
var rowValues=sheet.getRange(i,1,2,sheet.getLastColumn()).getValues();
if(rowValues[0][7] == "done" || rowValues[0][1] == "" && rowValues[1][1] != ""){
sheet.deleteRow(i)
}
}
}
}
这将删除B列(数组条目[1])中的单元格为空,而其下方的单元格具有值的所有行。希望我理解得对,这是您想要的功能。
此外,请删除parseInt(),这对于您的代码不是必需的。
答案 2 :(得分:0)
@ziganotschka 感谢您的指导。我不知道循环在删除一行后不会检查数据表的状态。
您的解决方案有效。但是,它似乎要慢得多。我发现的另一种方法是,将一个函数调用添加到我的循环中,以便它根据需要经常通过工作表。
我设置为简单地限制范围,使其在包含书面数据的最后一个单元格中结束(通过使用工作表中的公式),并简化功能,使其成为他的第一个答案中指出的五元素。
它看起来像这样:
function sheetclear(){
var ss = SpreadsheetApp.getActiveSpreadsheet();
var sheet = ss.getSheetByName("Sheet");
var fr = 5;
var lr = sheet.getRange("i3").getValue() //this is where I calculate the last occupied cell
var range = sheet.getRange(fr,1,lr,8)
var val = range.getValues()
if(sheet.getRange("h3").getValue() == true){
for (var i = lr; i>=fr; i--){
if(val[i-fr][1] == "" || val[i-fr][7] == "done"){
sheet.deleteRow(i)
}
}
//Re-adding the deleted rows and formating them
sheet.insertRowsAfter(sheet.getLastRow(),100-sheet.getLastRow());
sheet.getRange(fr,1,sheet.getLastRow(),8).setBorder(false, true, false, true, true, false, "silver",SpreadsheetApp.BorderStyle.SOLID)
sheet.getRange("h3").setValue(false);
}
}