更有效的删除关键字'功能

时间:2018-01-25 20:48:07

标签: javascript google-sheets google-spreadsheet-api

之前,我曾询问过如何删除重复项'功能更高效。我得到了Jordan Runner和Ed Nelson在其他地方的帮助,由此产生的代码对我的工作产生了巨大的积极影响。我有一个'删除关键字'功能也适用于少于1,500行的纸张。但是任何更大的东西都需要永远,有时甚至会超过“超过最长的执行时间”。

如果有两三个关键字,即使我的代码也可以正常运行。然而,我需要从有时超过20,000行(2列)的工作表中删除大约1,000个关键字。有了这么大的纸张,我的代码不适合用途,我会把我的纸张分解成2k件。有人可以帮助使代码可操作甚至大约20,000行,并且需要删除1,000个关键字?

function removeKeywords() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var rows = sheet.getDataRange();
  var numRows = rows.getNumRows();
  var values = rows.getValues();
  var rowsDeleted = 0;

  for (var i = 0; i <= numRows - 1; i++) {
    var row = values[i];

    if (row[0].toLowerCase().indexOf("keyword1") > -1) {
      sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
      rowsDeleted++;
    }

    if (row[0].toLowerCase().indexOf("keyword2") > -1) {
      sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
      rowsDeleted++;
    }

    if (row[0].toLowerCase().indexOf("keyword3") > -1) {
      sheet.deleteRow((parseInt(i)+1) - rowsDeleted);
      rowsDeleted++;
    }
  }
}

如其他地方所述,我是自学成才。

2 个答案:

答案 0 :(得分:1)

您需要创建异步函数,或者您可以使用WebWorkers。在此处查看如何使用WebWorkers:systemd.unit man page

现在,我可以举一个没有WebWorkers的例子,并在javascript中使用setTimeout()函数。

function removeKeywords() {
    var sheet = SpreadsheetApp.getActiveSheet();
    var rows = sheet.getDataRange();
    var numRows = rows.getNumRows();
    var values = rows.getValues();
    var rowsDeleted = 0;


    var i = 0;

    function deleteRows() {
        setTimeout(function() {
            if (i <= numRows) {
                var row = values[i];

                if (row[0].toLowerCase().indexOf("keyword1") > -1) {
                    sheet.deleteRow((parseInt(i) + 1) - rowsDeleted);
                    rowsDeleted++;
                }

                if (row[0].toLowerCase().indexOf("keyword2") > -1) {
                    sheet.deleteRow((parseInt(i) + 1) - rowsDeleted);
                    rowsDeleted++;
                }

                if (row[0].toLowerCase().indexOf("keyword3") > -1) {
                    sheet.deleteRow((parseInt(i) + 1) - rowsDeleted);
                    rowsDeleted++;
                }

                i += 1;
                deleteRows();
            }
        }, 25);
    }

    deleteRows();
}

当然,这比使用网络工作者要慢,但至少它不会阻止你的浏览器。

有关setTimeout() Using web workers

的更多信息

答案 1 :(得分:1)

您是否正在寻找问题的解决方案?如果你正在做,这个示例脚本怎么样?修改要点如下。

修改要点:

  • deleteRow()是通过覆盖使用反映搜索结果的数据来实现的,因为deleteRow()的费用很高。
  • 数组用于搜索关键字。

修改后的脚本:

function removeKeywords() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getDataRange();
  var values = range.getValues();
  var formulas = range.getFormulas();
  var keywords = ["keyword1", "keyword2", "keyword3"]; // Please set keywords here.
  var resValues = [];
  for (var i in values) {
    if (keywords.filter(function(e){return ~values[i][0].indexOf(e)}).length == 0) {
      resValues.push(values[i]);
    }
  }
  var res = [];
  resValues.forEach(function(e1, i1) {
    var temp = [];
    e1.forEach(function(e2, i2) {
      temp.push(formulas[i1][i2] ? formulas[i1][i2] : e2);
    });
    res.push(temp);
  });
  sheet.clearContents();
  sheet.getRange(1, 1, res.length, res[0].length).setValues(res);
}

注意:

  • 使用此示例脚本时,请准备一份示例电子表格并运行它。或者请使用复制的电子表格。

如果这对你没用,我很抱歉。

编辑:

function removeKeywords() {
  var sheet = SpreadsheetApp.getActiveSheet();
  var range = sheet.getDataRange();
  var values = range.getValues();
  var formulas = range.getFormulas();
  var keywords = ["keyword1", "keyword2", "keyword3"]; // Please set keywords here.
  var resValues = [];
  var removedRows = [];
  for (var i in values) {
    if (keywords.filter(function(e){return ~values[i][0].indexOf(e)}).length == 0) {
      resValues.push(values[i]);
    } else {
      removedRows.push(values[i]);
    }
  }
  var res = [];
  resValues.forEach(function(e1, i1) {
    var temp = [];
    e1.forEach(function(e2, i2) {
      temp.push(formulas[i1][i2] ? formulas[i1][i2] : e2);
    });
    res.push(temp);
  });
  sheet.clearContents();
  sheet.getRange(1, 1, res.length, res[0].length).setValues(res);
  Logger.log(res)
  Logger.log(removedRows) // Removed rows
}