如何用Apps Script每日定时复制单元格值逐行留存历史并解决相关报错
原有脚本问题拆解
- 行列数不匹配报错的成因:原脚本将目标写入范围设为
B2:B999(共998行),但从N15单元格读取到的是仅1行的单值数据,setValues()方法要求传入数据的行列数必须和目标范围完全对齐,因此触发行列数不匹配的异常。 - 逐行追加失效的成因:原脚本没有做动态定位逻辑,固定操作大段目标范围,既无法识别上次的写入位置,也不会自动移动到下一个空行。
修正后的完整可用脚本
function backup(){ // 脚本配置区,可根据实际需求直接调整参数 const SOURCE_SHEET_NAME = "Portfolio"; const SOURCE_CELL_POSITION = "N15"; const TARGET_SHEET_NAME = "Suivi perfs journalières"; const TARGET_COLUMN_INDEX = 2; // B列的索引值(A列=1,B列=2,以此类推) const currentSpreadsheet = SpreadsheetApp.getActiveSpreadsheet(); // 读取Portfolio表N15的当前数值 const sourceSheet = currentSpreadsheet.getSheetByName(SOURCE_SHEET_NAME); const metricValue = sourceSheet.getRange(SOURCE_CELL_POSITION).getValue(); // 自动定位本次要写入的目标行 const targetSheet = currentSpreadsheet.getSheetByName(TARGET_SHEET_NAME); const sheetLastRow = targetSheet.getLastRow(); let writeRow = 2; // 默认首日写入位置为B2 // 若目标表已有历史数据,从B列最后一行向上查找最近的非空单元格,将写入位置设为该单元格的下一行 if (sheetLastRow >= 2) { const columnData = targetSheet.getRange(2, TARGET_COLUMN_INDEX, sheetLastRow - 1, 1).getValues(); for (let i = columnData.length - 1; i >= 0; i--) { if (columnData[i][0] !== "") { writeRow = i + 3; // 数组索引i对应的实际行号为i+2,下一行即为i+3 break; } } } // 将数值写入定位完成的单元格 targetSheet.getRange(writeRow, TARGET_COLUMN_INDEX).setValue(metricValue); }
落地使用步骤
- 用上述代码替换原有脚本,首次运行时完成账号授权,手动测试一次,确认数值能正确写入B2且无报错。
- 在Apps Script控制台左侧进入「触发器」页面,新建时间驱动的定时任务,选择每日固定时间执行(建议设置为Portfolio表数据更新完成后的时段,比如收盘后15分钟),绑定上述
backup函数,即可实现每日自动追加记录。 - 后续如果需要调整源单元格、目标列位置,仅需修改脚本顶部配置区的常量值即可,无需改动核心逻辑。
内容的提问来源于stack exchange,提问作者Demeterro
相关产品推荐
相关产品推荐

