Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/google-sheets/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google apps script 控制电子表格的确定';getLastRow的最后一行_Google Apps Script_Google Sheets - Fatal编程技术网

Google apps script 控制电子表格的确定';getLastRow的最后一行

Google apps script 控制电子表格的确定';getLastRow的最后一行,google-apps-script,google-sheets,Google Apps Script,Google Sheets,我的Google工作表中有一个脚本,当“工作历史”中的单元格AV被清除时,它会将一行数据从我的“工作历史”工作表复制到“工作日程”工作表。如果在“作业计划表”上有完全空行,这很好,但是目标页上的一些列包含公式和其他字符,这导致 GETLASTROW()/将它们视为包含数据的行。 如何定义最后一行是什么?有没有办法让我只检查行中的一个单元格来确定它是否是最后一行?这是我的剧本: function onEdit(event) { var editedCell; var ss = Spread

我的Google工作表中有一个脚本,当“工作历史”中的单元格AV被清除时,它会将一行数据从我的“工作历史”工作表复制到“工作日程”工作表。如果在“作业计划表”上有完全空行,这很好,但是目标页上的一些列包含公式和其他字符,这导致 GETLASTROW()/<代码>将它们视为包含数据的行。 如何定义最后一行是什么?有没有办法让我只检查行中的一个单元格来确定它是否是最后一行?这是我的剧本:

function onEdit(event) {
  var editedCell;
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var s = event.source.getActiveSheet();
  var r = event.source.getActiveRange();

  if(s.getName() == "Job History" && r.getColumn() == 47 && r.getValue() == "") {
    var row = r.getRow();
    var numColumns = s.getLastColumn();
    var targetSheet = ss.getSheetByName("Job Schedule");
    var target = targetSheet.getRange(targetSheet.getLastRow() + 1, 1, 1, numColumns);
    var source = s.getRange(row, 1, 1, numColumns);
    var notes = source.getNotes();
    source.copyTo((target), {contentsOnly:true});
    target.setNotes(notes);
    s.deleteRow(row);
  }
}

请看。它创建的脚本用于在第47列单元格中接收到
“X”
时将行从“作业计划”表移动到“作业历史记录”表,并在接收到
“H”
时将行移动到“作业保留”表。这样做没有任何问题,但当我尝试从历史记录中“反转”此移动,并在清除第47列值时将工作表保留回明细表时,不会发生这种情况,因为“空”行中的某些单元格使用公式和一些字符格式化,因此,如果一行可以被视为空的,例如,如果列B中的单元格是空的,那么我认为它会工作。

虽然您不能改变
工作表#getLastRow
的操作方式,但您可以使用它来限制您的搜索空间-也就是说,不需要检查最后一行中的每一行(由
getMaxRow()
给出的行)在找到一个非空单元格之前,可以从
getLastRow()
行向上移动

您可以采取两种方法-一种是模拟按下
Ctrl
+
Up
,另一种是测试单元格

模拟按键/连续距离检测 这将使用该方法,然后沿相反方向偏移一次(因为它会选择下一个包含数据的边单元(或图纸的边))。它永远不会返回工作表中的第一行

// Will throw if called on an expanding arrayformula column. Adds a new row if needed.
function getTargetRowInColumn_(sheet, columnIndex) {
  const maxRow = sheet.getMaxRows();
  // If the last row is the max row (e.g. an expanding arrayformula is present in a column),
  // then accessing getLastRow() + 1 will silently fail.
  var r = sheet.getRange(maxRow, columnIndex + 1);;
  if (sheet.getLastRow() === maxRow &&
     (r.getValue() !== "" || r.getFormula()))
  {
    // We want either the next row (which we will create), or there is a formula
    // that will add values to this column - user error for accessing this column.
    sheet.insertRowsAfter(maxRow, 1);
    SpreadsheetApp.flush();
    r = r.offset(1, 0);
    if (r.getValue() !== "" || r.getFormula())
      throw new RangeError("target column index '" + columnIndex + "' has expanding formula");
    
    return ++maxRow; // Same output as r.getRow(), but faster.
  }
  
  r = r.getNextDataCell(SpreadsheetApp.Direction.UP);
  do {
    r = r.offset(1, 0);
  } while (r.getValue());
  return r.getRow();
}
编辑:因为简单的触发器调用不会显示错误,所以您不会看到任何问题的可视通知-您必须检查Stackdriver上的脚本日志。我添加了一些越界
Range
访问的健全性检查,即使在允许显示错误消息的上下文中运行,通常也会导致无声故障

价值测试 这将使用对和的批处理调用,然后再也不会使用该工作表。这里我们测试数组索引是否为空字符串(
“”
),如果为空,则要求索引中也没有公式。
getValues
getFormulas
都会为“no value/formula”返回一个空字符串,并且由于公式可能会故意返回值
,因此都需要进行检查

// Does not throw if called on an expanding arrayformula column. Does not add a new row.
function getTargetRowInColumn_(sheet, columnIndex) {
  var lastRow = sheet.getLastRow();
  const r = sheet.getRange(1, columnIndex + 1, lastRow, 1);
  const values = r.getValues();
  const formulas = r.getFormulas();
  do {
    --lastRow;
  // isEmptyString = values[lastRow][0] === "";
  // isNotAFormula = !formulas[lastRow][0];
  //          isEmptyStringValue     &&     isNotAFormula
  } while (values[lastRow][0] === "" && !formulas[lastRow][0]);
  // lastRow now points to an array index that is occupied by either a formula or value.
  // += 1 converts from array index to Range row, and then += 1 again
  // (since we want the next row, which is empty).
  lastRow += 2;
  return lastRow;
}
值测试方法将为您提供最大的灵活性,因为您可以准确地定义是什么控制对
lastRow
变量的更改。但是,由于您精确地定义了对<代码> LASSTROW 变量的控制,您必须考虑与比较和短路操作符相关的可能陷阱,并且数据存储在您的表中。连续范围检测从您的控件中删除所有这些内容,这是好是坏(取决于您的特定任务)。请注意,上面的两个示例都使用列索引,而不是列。“A”是0,“B”是1,以此类推。如果你想改变它,一定要这样做


示例用法,每当编辑任何工作表上的任何单元格时,将弹出一个toast,其中包含电子表格中第一个工作表的前3列中下一个空白单元格的行号

function onEdit(e) {
  const all = e.source.getSheets();
  var message;
  try {
    message = ["eh?", "bee", "see"].map(function (colName, i) {
      return [
        "Column '" + colName + "'",
        "(index " + i + "):",
        getTargetRowInColumn_(all[0], i)
      ].join(" ");
    }).join("; ");
  } catch (err) {
    message = err.message;
  }
  e.source.toast(message, "Row of the next blank cell in first sheet", 60);
  // Datestamp the next empty cell in column A of the first sheet.
  var targetColumn = 1; // Column A
  all[0].getRange(getTargetRowInColumn_(all[0], targetColumn - 1), targetColumn).setValue(new Date());
}

您希望检索每列最后一行的行号。我的理解正确吗?@Tanaike谢谢你的回复-我想检索某个特定列最后一行的行号。谢谢你的回复。如果特定列是常量,我可以问你吗?@Tanaike谢谢你问你是否可以问常量列-可以。@Tanaike你想知道什么?我仍在努力使这项工作,任何帮助是感激的!谢谢你的回复;我试过使用这两种方法,但一定是做错了什么。将其添加到当前脚本并使其运行而不是getLastRow的正确方法是什么?@J.Kubassek我添加了一个使用它的示例,并修复了第一个脚本的一些问题method@tehhowh好极了!第1(B)列实际上是正确的。那么在我的例子中,我将如何选择整个行范围?这不起作用:var target=targetSheet.getRange(targetSheet.getTargetRowinColumn_389;()+1,1,1,numColumns)@J.Kubassek
getTargetRowInColumn_(…)
不是属于
Sheet
类的方法,因此不能像
targetsheet.getTargetRowInColumn(…)
那样调用它。当有疑问时,请保持简单:
var targetRow=getTargetRowInColumn_(targetSheet,targetColumn-1);targetSheet.getRange(targetRow,targetColumn,.
(其中
targetColumn
基于1,函数假设基于0的输入)@tehhowh好的,我现在越来越近了,但我不明白targetColumn变量应该如何替换我以前的numColumns变量。