1

我一直在做一个个人项目,遇到了一个问题,即当存在隐藏数据(例如复选框)时,我无法弄清楚如何获取特定表的最后一行。' 我一直在研究这个主题并遇到了一个可能的解决方案,但我不确定如何将它融入我的代码中,或者我是否可以将它整合到我的代码中,因为坦率地说,我对编码语言还不是很流利。

以下代码归功于原作者 ( https://yagisanatode.com/ ):

function getLastRowSpecial(range){
   var rowNum = 0;
   var blank = false;
 for(var row = 0; row < range.length; row++){
 if(range[row][0] === "" && !blank){
  rowNum = row;
  blank = true;
} 
else if (range[row][0] !== ""){
    blank = false;
   };
};
 return rowNum;
};

这是我当前的代码:

function onEdit(event) {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var currentSh = event.source.getActiveSheet();
  var currentCell = event.source.getActiveRange();

if (currentSh.getName() == 'invoice_approval' && currentCell.getColumn() == 5 && currentCell.getValue()== 'Approved') {

 var row = currentCell.getRow();
 var numColumns = currentSh.getLastColumn();

  var targetSh = ss.getSheetByName('open_invoices');
  var target = targetSh.getRange(targetSh.getLastRow()+1, 1);
  currentSh.getRange(row,1,1,numColumns).moveTo(target);
  currentSh.deleteRow(row);
}
// (Moving back rows <open_invoices to invoice_approval> when a cell's value is changed from 'Approved')

else if (currentSh.getName() == 'open_invoices' && currentCell.getColumn() == 5 && currentCell.getValue()!= 'Approved' ) {

   var row = currentCell.getRow();
   
  var targetSh = ss.getSheetByName('invoice_approval');
  var target = targetSh.getRange(targetSh.getLastRow()+1, 1);
  currentSh.getRange(row,1,1,5).moveTo(target);
  currentSh.deleteRow(row);

}
}

我制作了一个样本表并列出了我面临的问题:

https://docs.google.com/spreadsheets/d/1Yol5FAa3Sw84zRDanOCILUhD1IWMKjrHAJewT-P18to/edit?usp=sharing

4

1 回答 1

0

我相信你的目标如下。

  • 当“invoice_approval”表的“E”Approved列为 时,您想将该行移动到“open_invoices”表的第一个空行。
  • 当“open_invoices”表的“E”列不是 NOTApproved时,您希望将该行移动到“invoice_approval”表的第一个空行。

在这种情况下,如何进行以下修改?

修改后的脚本:

function onEdit(event) {
  // This sample script is from https://stackoverflow.com/a/44563639
  Object.prototype.get1stEmptyRowFromTop = function (columnNumber, offsetRow = 1) {
    const range = this.getRange(offsetRow, columnNumber, 2);
    const values = range.getDisplayValues();
    if (values[0][0] && values[1][0]) {
      return range.getNextDataCell(SpreadsheetApp.Direction.DOWN).getRow() + 1;
    } else if (values[0][0] && !values[1][0]) {
      return offsetRow + 1;
    }
    return offsetRow;
  };

  var {source, range} = event;
  var currentSh = source.getActiveSheet();
  var sheetName = currentSh.getSheetName();
  if (sheetName == 'invoice_approval' && range.columnStart == 5 && range.getValue() == 'Approved') {
    var row = range.rowStart;
    var numColumns = currentSh.getLastColumn();
    var targetSh = source.getSheetByName('open_invoices');
    var target = targetSh.getRange(targetSh.get1stEmptyRowFromTop(1), 1);
    currentSh.getRange(row, 1, 1, numColumns).moveTo(target);
    currentSh.deleteRow(row);
  } else if (sheetName == 'open_invoices' && range.columnStart == 5 && range.getValue() != 'Approved') {
    var row = range.rowStart;
    var targetSh = source.getSheetByName('invoice_approval');
    var target = targetSh.getRange(targetSh.get1stEmptyRowFromTop(1), 1);
    currentSh.getRange(row, 1, 1, 5).moveTo(target);
    currentSh.deleteRow(row);
  }
}
  • 在此脚本中,使用了事件对象。Ref使用事件对象时,可以减少一点处理成本。参考
  • 为了从工作表顶部检索第一个空行,我使用了这个线程的示例脚本。

参考:

于 2021-10-16T23:20:37.833 回答