You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Google脚本中存储getLastRow()值并复用以仅复制新增表单数据?

嗨,这个需求在Google Apps Script开发里挺常见的,要实现这种跨脚本运行的持久化值存储,最实用的有两种方法,我给你一步步讲清楚:

方法1:使用PropertiesService(首推)

这是Google官方提供的专门用于存储键值对的服务,非常适合存这种小标记值,而且数据会持久保存,哪怕你关闭脚本、重启文档都不会丢。它有三种存储范围,这里用脚本属性或者文档属性都可以,前者是绑定到这个脚本,后者是绑定到当前文档,根据你的需求选就行。

先写两个辅助函数来获取和设置prevRow:

// 获取上次存储的最后行数
function getPrevRow() {
  // 用getDocumentProperties()的话,值会和当前文档绑定,换文档脚本就不认了
  const props = PropertiesService.getScriptProperties();
  // 初始值设为1,因为表单响应表第一行一般是表头
  return parseInt(props.getProperty('prevRow')) || 1;
}

// 更新存储的最后行数
function setPrevRow(rowNum) {
  const props = PropertiesService.getScriptProperties();
  props.setProperty('prevRow', rowNum.toString());
}

然后是核心的复制新增行的函数:

function copyNewResponses() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  // 替换成你的表单响应表名称
  const responseSheet = ss.getSheetByName('表单响应');
  // 替换成你的目标计算表名称
  const targetSheet = ss.getSheetByName('计算表');

  const currentLastRow = responseSheet.getLastRow();
  const prevRow = getPrevRow();

  // 检查是否有新增的响应行
  if (currentLastRow > prevRow) {
    // 计算新增行数,确定要复制的范围
    const rowsToCopy = currentLastRow - prevRow;
    const rangeToCopy = responseSheet.getRange(prevRow + 1, 1, rowsToCopy, responseSheet.getLastColumn());
    
    // 复制到目标表的最后一行之后,这里用PASTE_VALUES只粘贴值,避免格式干扰
    rangeToCopy.copyTo(targetSheet.getRange(targetSheet.getLastRow() + 1, 1), SpreadsheetApp.CopyPasteType.PASTE_VALUES, false);
    
    // 更新存储的最后行数,下次运行就从这里开始
    setPrevRow(currentLastRow);
    Logger.log(`成功复制${rowsToCopy}条新增响应数据`);
  } else {
    Logger.log('没有发现新增的表单响应');
  }
}
方法2:使用隐藏工作表存储

如果你更喜欢可视化管理这个存储值,也可以建一个隐藏的工作表来存prevRow,适合需要偶尔手动修改标记值的场景:

// 从隐藏工作表获取上次的最后行数
function getPrevRowFromSheet() {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  let storageSheet = ss.getSheetByName('存储表');
  
  // 如果工作表不存在,就创建并隐藏,设置初始值
  if (!storageSheet) {
    storageSheet = ss.insertSheet('存储表');
    storageSheet.hideSheet();
    storageSheet.getRange(1, 1).setValue(1);
  }
  
  return parseInt(storageSheet.getRange(1, 1).getValue()) || 1;
}

// 更新隐藏工作表里的最后行数
function setPrevRowToSheet(rowNum) {
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  const storageSheet = ss.getSheetByName('存储表');
  storageSheet.getRange(1, 1).setValue(rowNum);
}

把核心函数里的getPrevRow()和setPrevRow()换成上面这两个就行,逻辑完全一致。

注意事项

  • 初始值设为1是因为表单响应表的第一行通常是表头,第一次运行会把所有已有的响应行(从第2行开始)复制过去,之后就只会复制新增的。
  • 如果你的响应表有手动删除行的情况,可能需要额外做校验,但一般表单响应表不会这么操作,所以默认逻辑足够用。

内容的提问来源于stack exchange,提问作者kev

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.27 09:35:25