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

使用Google App Script实现表格数据增量复制与筛选同步需求

Google Sheets 数据同步:避免重复追加仅同步新数据

需求场景

  • 表格1的GIORNALIERA标签页是Google Forms的响应存储页,每日会新增表单提交数据,也存在手动删除行的操作;
  • 表格2的Foglio13标签页需要仅追加源表格的新数据,且已同步的数据即使在源表格中被删除,也要在目标表格保留;
  • 表格2的另一指定标签页(比如命名为LUKE_DATA),需要仅追加源表格中指定员工(如Luke Skywalker)的未同步过的新数据,同样保留已同步内容。

现有问题

当前使用的代码每次运行会将源表格所有数据追加到目标页,导致大量重复数据:

function copyInfo() {
  var ss = SpreadsheetApp.getActiveSpreadsheet();
  var copySheet = ss.getSheetByName("PANORAMICA");
  var pasteSheet = ss.getSheetByName("Foglio13");

  var rows = copySheet.getDataRange().getValues(); // Gets the rows with data

  rows.map(row => pasteSheet.appendRow(row)); // Appends the rows to the second sheet
}

解决方案代码

通用同步逻辑(针对需求2)

利用Google Forms默认生成的时间戳列(第一列,唯一标识每一条表单提交)作为判断依据,先收集目标页已有的所有时间戳,再过滤源数据中未同步的行进行追加:

function syncNewDataToFoglio13() {
  // 替换成你的实际表格ID
  var sourceSpreadsheetId = "源表格1的ID";
  var targetSpreadsheetId = "表格2的ID";

  // 获取源、目标表格的对应标签页
  var sourceSheet = SpreadsheetApp.openById(sourceSpreadsheetId).getSheetByName("GIORNALIERA");
  var targetSheet = SpreadsheetApp.openById(targetSpreadsheetId).getSheetByName("Foglio13");

  // 获取源数据(跳过表头,若源无表头可删除.slice(1))
  var sourceRows = sourceSheet.getDataRange().getValues().slice(1);
  if (sourceRows.length === 0) return;

  // 把目标页已有的时间戳存入Set,方便快速查重
  var targetTimestamps = new Set();
  var targetRows = targetSheet.getDataRange().getValues();
  targetRows.forEach(row => {
    if (row[0]) targetTimestamps.add(row[0].toString());
  });

  // 过滤出源数据中未同步的行
  var newRowsToSync = sourceRows.filter(row => {
    return !targetTimestamps.has(row[0].toString());
  });

  // 批量写入新数据(比逐行appendRow效率高很多)
  if (newRowsToSync.length > 0) {
    targetSheet.getRange(targetSheet.getLastRow() + 1, 1, newRowsToSync.length, newRowsToSync[0].length).setValues(newRowsToSync);
  }
}

指定员工数据同步(针对需求3)

在通用逻辑基础上,增加员工姓名过滤条件:

function syncLukeDataToTargetSheet() {
  var sourceSpreadsheetId = "源表格1的ID";
  var targetSpreadsheetId = "表格2的ID";
  var targetSheetName = "LUKE_DATA"; // 替换成存储指定员工数据的标签页名称
  var targetEmployee = "Luke Skywalker"; // 指定员工姓名

  var sourceSheet = SpreadsheetApp.openById(sourceSpreadsheetId).getSheetByName("GIORNALIERA");
  var targetSheet = SpreadsheetApp.openById(targetSpreadsheetId).getSheetByName(targetSheetName);

  var sourceRows = sourceSheet.getDataRange().getValues().slice(1);
  if (sourceRows.length === 0) return;

  // 获取目标页已有的时间戳集合
  var targetTimestamps = new Set();
  var targetRows = targetSheet.getDataRange().getValues();
  targetRows.forEach(row => {
    if (row[0]) targetTimestamps.add(row[0].toString());
  });

  // 过滤条件:未同步 + 员工姓名匹配(假设姓名在第3列,索引2,根据实际列位置修改)
  var newRowsToSync = sourceRows.filter(row => {
    return !targetTimestamps.has(row[0].toString()) && row[2] === targetEmployee;
  });

  if (newRowsToSync.length > 0) {
    targetSheet.getRange(targetSheet.getLastRow() + 1, 1, newRowsToSync.length, newRowsToSync[0].length).setValues(newRowsToSync);
  }
}

关键说明

  1. 唯一标识替换:如果表单没有时间戳列,可替换为其他唯一ID列(比如表单响应ID),确保每条数据有唯一区分标识;
  2. 表头适配:若源数据无表头,删除代码中的.slice(1)即可;
  3. 表格ID获取:打开对应表格,URL中d/和/edit之间的字符串就是表格ID;
  4. 效率优化:使用setValues批量写入代替appendRow逐行写入,同步大量数据时速度差异明显。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 17:31:14