使用从 Google Sheet 的有限范围时如何找到正确的 rowId?

How to find the correct rowId when using a limited range from Google Sheet?

我有以下代码通过 sheet 检查单词“CASH”。一旦找到,它将复制该行到一个新的 sheet 然后删除该行。

之前,我的值范围是这样设置的:

var range = ss1.getRange(2, 1, lr, lc);

但是现在我的 sheet 有 6000 多行,这是非常低效的。我已经更改了它,以便它只查看 lr-100 的范围,这样就不必挖掘得那么深。

进行该更改后,我用于删除行的旧代码 ss1.deleteRow(i+2) 不再有效,因为 i 仅在特定 range 中引用该行(即,如果它是这 100 行中的第 90 行,i = 90,这将最终删除我的 sheet 中的第 90 行,例如,它应该是 6500。

问题如何以我的脚本设置的这种新方式找到正确的行#?

var etfar = ["BOTZ"]


function doCash() {
    for (var i = 0; i < etfar.length; i++) {
    cashMoney(etfar[i])
    }
};

 
function cashMoney(etf) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var ss1 = ss.getSheetByName(etf);
  var ss2 = ss.getSheetByName("Cash");

  var lr = ss1.getLastRow();
  var lc = ss1.getLastColumn();

var range = ss1.getRange(lr-100, 1, lr, lc);
var data = range.getValues();

for (var i = data.length - 1; i >= 0; i--)
 {
  var check = data[i][4] // ith row, 3rd column
  if (check.includes("CASH")) { 

 var rowUsd = data[i];
 
// something has to happen here to find the exact row

 ss2.appendRow(rowUsd);
 //ss1.deleteRow(i+2); <-- this is old code. Prior, in my 'range' I used to start my rows from "2", but that was highly inefficient and I've changed it to "lr-100" so that it begins checking from the last 100 rows instead
    }
};
};

我想这就是你想要的

function cashMoney(etf) {
  var ss = SpreadsheetApp.getActive();
  var sh1 = ss.getSheetByName(etf);
  var sh2 = ss.getSheetByName("Cash");
  var lr = sh1.getLastRow();
  var lc = sh1.getLastColumn();
  var range = sh1.getRange(lr - 100, 1, 101, lc);
  var data = range.getValues();
  var d = 0;
  for (var i = data.length - 1; i >= 0; i--) {
    var check = data[i][4] // ith row, 3rd column
    if (check.includes("CASH")) {
      var rowUsd = data[i];
      sh2.appendRow(rowUsd);
      sh.deleteRow(lr - 100 + i - d++);The row is data start row + i 
    }
  };
}

d 跟踪已从电子表格中删除的行,这是必需的,因为它们尚未从数据集中删除。

来自now that my sheet has 6000+ rows, this is highly inefficient.,你的情况,为了减少脚本的处理成本,使用SheetsAPI怎么样?当 Sheets API 用于您的情况时,可能能够处理所有行。当 Sheets API 用于您的脚本时,它变成如下。

修改后的脚本:

此脚本使用表格 API。所以,please enable Sheets API at Advanced Google services。并且,请设置 etfar.

function sample() {
  var etfar = ["Sheet1", "Sheet2",,,]; // Please set your sheet names.

  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var dstSheet = ss.getSheetByName("Cash");
  var dstSheetId = dstSheet.getSheetId();
  var lastRow = dstSheet.getLastRow();
  var { copyRows, deleteRows } = etfar.reduce((o, e) => {
    var srcSheet = ss.getSheetByName(e);
    var srcSheetId = srcSheet.getSheetId();
    srcSheet.getRange("E2:E" + srcSheet.getLastRow()).getValues().forEach(([v], i) => {
      if (v == "CASH") {
        o.copyRows.push({ copyPaste: { source: { sheetId: srcSheetId, startRowIndex: i + 1, endRowIndex: i + 2, startColumnIndex: 0 }, destination: { sheetId: dstSheetId, startRowIndex: lastRow, endRowIndex: lastRow + 1, startColumnIndex: 0 } } });
        o.deleteRows.push({ deleteDimension: { range: { sheetId: srcSheetId, dimension: "ROWS", startIndex: i + 1, endIndex: i + 2 } } });
        lastRow++;
      }
    });
    return o;
  }, { copyRows: [], deleteRows: [] });
  var requests = [...copyRows, ...deleteRows.reverse()];
  if (requests.length == 0) return;
  Sheets.Spreadsheets.batchUpdate({ requests }, ss.getId());
}
  • 当此脚本为运行时,“E”列搜索的值是从etfar的sheet中检索的,这些值是附加到目的地 sheet“现金”。而且,每个 sheet 的复制行都被删除。

  • 在这个脚本中,这些进程可以通过一次 API 调用 运行。

注:

  • 当我看到你的脚本时,来自 var check = data[i][4] // ith row, 3rd column,我认为 data[i][4] 是列“E”。但是你说3rd column。这是“C”列。如果要从“C”列中查找“CASH”的值,请将getRange("E2:E" + srcSheet.getLastRow())修改为getRange("C2:C" + srcSheet.getLastRow())

参考文献: