首页 > 解决方案 > 有没有一种有效的方法可以在谷歌应用程序脚本的一列单元格中搜索和附加字符串?

问题描述

正如标题所说,我目前正在运行一个我认为可能更有效的功能。

本质上,我的电子表格中有一个列 (k),我正在查找其中的文本"delete"。如果找到该文本,那么我只需附加", removed"到它。这让运行在电子表格之外的 Appsheet 知道在看到文本时不显示该行"removed"

例如,函数运行后 col k 的随机行可能如下所示: delete, completed, removed

这里的问题是我们的工作表有 4000 行,并且需要 1000 秒以上才能完成。当然,必须有一种更快的方法来搜索和附加文本,而不是通过 for 循环对工作表中的每一行进行迭代。

function removeDeleted() {
  var ss = SpreadsheetApp.openById(BD_SPREADSHEET_ID);
  var data = ss.getSheetByName(DATA_TAB);
  var dataRange = data.getDataRange().getValues();
  var colData = [];

  for (var i = 1; i < dataRange.length; i++) {
    colData.push(dataRange[i][0]);
  }

  for (var i = 0; i < colData.length; i++) {

    // Take every cell except the first row on col Q (11), as that is the header
    var comments_cell = data.getDataRange().getCell(i + 2, 11).getValue();

    // Check for string "delete" inside cell
    if (comments_cell.toString().indexOf("delete") !== -1 || comments_cell.toString().indexOf("Delete") !== -1) {

      // Check for string "removed" not already inside cell
      if (!(comments_cell.toString().indexOf("removed") !== -1)) {

        // Append ", removed"
          data.getDataRange().getCell(i + 2, 11).setValue(comments_cell + ", removed");
      }
    }
  }
}

我仍在学习谷歌应用程序脚本和电子表格集成,所以我觉得这两个 for 循环可能有些冗余。任何帮助,将不胜感激。

标签: stringgoogle-apps-scriptgoogle-sheetsprocessing-efficiency

解决方案


我尚未对此进行测试,但我认为这应该可以满足您的需要。我已经评论了每一行以帮助解释逻辑。

您可以像我在下面所做的那样批量写入所有数据,或者将其写入循环中。如果您要进行大量写入/更新,那么批量进行会更好。

function removeDeleted()
{
    // get the spreadsheet
    var ss = SpreadsheetApp.openById(BD_SPREADSHEET_ID);

    // get the sheet
    var dataSheet = ss.getSheetByName(DATA_TAB);

    // get the values of the data range as a 2D array
    var data = dataSheet.getDataRange().getValues();

    // first row (index = 0) is header
    // get the index of the column we want to check
    var columnToCheck = data[0].indexOf("COLUMN NAME");

    // track if any data is changed
    var dataChanged = false;

    // go through each row
    // skip the first row since its the header row
    for(var i = 1, numRows = data.length; i < numRows; ++i)
    {
        // get the cell value for the current row and column we want
        var cellValue = data[i][columnToCheck];

        // only if the cell value has delete in it
        if(cellValue.match(/delete/i))
        {
            // only if the cell value does not have removed in it
            if(!cellValue.match(/removed/i))
            {
                // update the value in the 2D array
                data[i][columnToCheck] += ", removed";

                // mark that data changed so we know to write it back to the sheet later
                dataChanged = true;
            }
        }
    }

    // only if data actually changed
    if(dataChanged)
    {
        // write it back to the sheet
        dataSheet.getDataRange().setValues(data);
    }
}

推荐阅读