使用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); } }
关键说明
- 唯一标识替换:如果表单没有时间戳列,可替换为其他唯一ID列(比如表单响应ID),确保每条数据有唯一区分标识;
- 表头适配:若源数据无表头,删除代码中的
.slice(1)即可; - 表格ID获取:打开对应表格,URL中
d/和/edit之间的字符串就是表格ID; - 效率优化:使用
setValues批量写入代替appendRow逐行写入,同步大量数据时速度差异明显。
内容的提问来源于stack exchange,提问作者ItalSec
相关产品推荐
相关产品推荐

