2

我有这个脚本来删除某些行,如果所选列中的所选单元格具有提及的内容,但我不明白它在哪里失败

    function DeleteRowByKeyword() {

  var value_to_check = Browser.inputBox("Enter the keyword to trigger delete Row","", Browser.Buttons.OK);

  //  prendo quello attivo
  var DATA_SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  var FIRST_COLUMN = Browser.inputBox("Number of Column to look at (eg: for column A enter 1)","", Browser.Buttons.OK);

  ss.toast("removing duplicates...","",-1);

  var dataCopy1 = DATA_SHEET.getDataRange().getValues();
  var deleted_rows = 0;
  var rangeToCopy = '';

  if (dataCopy1.length > 0) {
    var i = 1;

    while (i < DATA_SHEET.getMaxRows() - deleted_rows) {
  if ((dataCopy1[i][FIRST_COLUMN]).search(value_to_check) != -1) {

    ss.deleteRow(i);
    deleted_rows++;
  } 
  i++;
    }
  }


  ss.toast("Done! " + deleted_rows + ' rows removed',"",5);
    }

提前感谢您的帮助

4

2 回答 2

4

有几点需要改进:

  • 请记住,对于 SpreadsheetApp 中的所有方法,电子表格的行和列从 1 开始编号,而 javascript 数组从 0 开始编号。使用两者时,您需要在这些数字基数之间进行调整。

  • 出于两个原因,该String.search()方法在这里可能是不合适的选择。将.search()匹配子字符串,因此 ('Testing').search('i')找到匹配项;您可能想要寻找完全匹配的内容。此外,.search()还包括对正则表达式匹配的支持,因此用户可能会惊讶地发现他们的输入被解释为正则表达式;.indexOf()可能是更好的选择。

  • 要将操作限制为包含数据的行,请使用.getLastRow() 而不是.getMaxRows().

  • 删除行时,电子表格的大小dataRange会变小;您确实考虑到了这一点,但是由于您要循环到最大大小,因此该要求使代码变得复杂。您可以通过从最大值向下循环来简化事情。

  • 列号的输入容易出错,所以让用户输入一个字母;您可以将其转换为数字。

  • 您尚未为ss(在此函数内)定义值。

这是更新的代码:

function DeleteRowByKeyword() {

  var value_to_check = Browser.inputBox("Enter the keyword to trigger delete Row", "", Browser.Buttons.OK);

  var matchCol = Browser.inputBox("Column Letter to look at", "", Browser.Buttons.OK);
  var FIRST_COLUMN = (matchCol.toUpperCase().charCodeAt(0) - 'A'.charCodeAt(0) + 1);  // Convert, e.g. "A" -> 1

  //  prendo quello attivo (get active sheet)
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var DATA_SHEET = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();

  ss.toast("removing duplicates...", "", -1);

  var dataCopy1 = DATA_SHEET.getDataRange().getValues();
  var deleted_rows = 0;

  if (dataCopy1.length > 0) {
    var i = DATA_SHEET.getLastRow();  // start at bottom

    while (i > 0) {
      if (dataCopy1[i-1][FIRST_COLUMN-1] === value_to_check) {

        ss.deleteRow(i);
        deleted_rows++;
      }
      i--;
    }
  }

  ss.toast("Done! " + deleted_rows + ' rows removed', "", 5);
}
于 2013-07-29T18:34:04.843 回答
1

您需要确保要删除的索引是正确的索引。当您删除一行时,所有波纹管行的索引都更改为-1。所以试试这个代码:

if (dataCopy1.length > 0) {
var i = 1;

while (i < DATA_SHEET.getMaxRows() - deleted_rows) {
 if ((dataCopy1[i][FIRST_COLUMN]).search(value_to_check) != -1) {

   ss.deleteRow(i - deleted_rows);
  deleted_rows++;
 } 
i++;
}
}
于 2013-07-29T18:02:44.557 回答