SpreadsheetApp.getLastRows() 提供空记录,不截断有数据的记录

SpreadsheetApp.getLastRows() provides empty records and not truncate to those with data

我是 JS 的新手,使用 Google App Script,所以请原谅我缺乏 JS 知识。

我有一个简单的 .gs 脚本可以工作。它将一个单元格中的内容转换为超链接(例如,如果文本是“blah”,它将是“https://example.com/blah”)。

脚本检索要操作的行数。对于一个 sheet,即使 sheet 有 1000 行,它也会正确执行并将其截断到最后一个条目(行=31)。但是,对于另一个 sheet,它不会和 returns 999:

这是错误时的调试:

Apr 8, 2022, 11:20:53 AM    Debug   doiColumn: 10   numRows: 999

这是另一个按预期工作的 sheet:

Apr 8, 2022, 9:44:47 AM Debug   doiColumn: 5   numRows: 31

docs 表示:“Returns 包含内容的最后一行的位置。”

为了便于说明,这里有一段代码:

let spreadsheet = SpreadsheetApp.getActive();
let sheet = SpreadsheetApp.getActiveSheet();
const column = getColumn(sheet, column_name);
let range = sheet.getRange(2, column, sheet.getLastRow() - 1, 1)
console.log(range.getValues());
const numRows = range.getNumRows();
console.log(`column: ${column}   numRows: ${numRows}`)

我想确保 .getLawRow() 被截断。否则这个脚本运行的时间比它应该的要长。

抱歉,我无法将其放入评论中

要求col=列号,sh=sheet(不是名字),ss=Spreadsheet(不是名字)

function getColumnHeight(col, sh, ss) {
  var ss = ss || SpreadsheetApp.getActive();
  var sh = sh || ss.getActiveSheet();
  var col = col || sh.getActiveCell().getColumn();
  var rcA = [];
  if (sh.getLastRow()){ rcA = sh.getRange(1, col, sh.getLastRow(), 1).getValues().flat().reverse(); }
  let s = 0;
  for (let i = 0; i < rcA.length; i++) {
    if (rcA[i].toString().length == 0) {
      s++;
    } else {
      break;
    }
  }
  return rcA.length - s;
  //const h = Utilities.formatString('col: %s len: %s', col, rcA.length - s);
  //Logger.log(h);
  //SpreadsheetApp.getUi().showModelessDialog(HtmlService.createHtmlOutput(h).setWidth(150).setHeight(100), 'Col Length')
}

还有其他方法可以做到这一点,但我更喜欢这个。这对我来说很可靠

使用这样的范围 sheet.getRange("A1:Z") 还将为您提供从 getLastRow() 到 getMaxRows() 的一堆空值,然后需要将其过滤掉,但如果您有你的数据中的一个 null 那么它也将被删除,现在你有虚假数据,因为该行被删除现在弄乱了你的行顺序。

尝试用

替换.getLastRow()
.getLastDataRow(column)

并添加这个原型函数

Object.prototype.getLastDataRow = function(col){
  var lastRow = this.getLastRow();
  if (col == null){col=1}
  var range = this.getRange(lastRow,col);
  if (range.getValue() !== "") {
    return lastRow;
  } else {
    return range.getNextDataCell(SpreadsheetApp.Direction.UP).getRow();
  }  
};