Google Sheets状态变更行移动脚本报错:TypeError读取source未定义
问题排查:Google Sheets脚本报错TypeError: Cannot read properties of undefined (reading 'source')
问题描述
我有一个名为Tracker的Google Sheet,包含Workload和Archive两个标签页。需编写脚本实现:当Workload标签页N列(带下拉菜单)的状态变为Complete或Cancelled时,将该行完整移动到Archive标签页底部的第一个空白行。但脚本无法运行,报错信息如下:
Error
TypeError: Cannot read properties of undefined (reading 'source')
onEdit @ Code.gs:7
原脚本代码:
function onEdit(e) { var sheetName = "Tracker"; var sourceTabName = "Workload"; var destinationTabName = "Archive"; var statusColumn = 14; // Column N var sheet = e.source.getSheetByName(sheetName); // Check if the edited cell is in the correct sheet and column if (e.range.getSheet().getName() == sourceTabName && e.range.getColumn() == statusColumn) { var statusValue = e.value; // Check if the status is "Cancelled" or "Complete" if (statusValue == "Cancelled" || statusValue == "Complete") { // Move the entire row to the destination tab moveRowToDestination(sheet, e.range.getRow(), destinationTabName); } } } function moveRowToDestination(sheet, row, destinationTabName) { var data = sheet.getRange(row, 1, 1, sheet.getLastColumn()).getValues()[0]; var destinationTab = sheet.getSheetByName(destinationTabName); destinationTab.appendRow(data); sheet.deleteRow(row); }
错误原因分析
事件对象
e未定义:
直接在脚本编辑器中手动运行onEdit函数时,Google Apps Script不会自动传入事件对象e,此时e为undefined,调用e.source就会触发该报错。onEdit是简单触发器,必须通过在表格中手动编辑单元格才能触发,才能获取到有效的事件对象。工作表概念混淆:
代码中sheetName变量存储的是整个表格的名称(Tracker),但e.source.getSheetByName()需要传入标签页名称。后续将错误的工作表对象传给moveRowToDestination函数,导致获取Archive标签页时逻辑错误。
修正后的代码
function onEdit(e) { // 校验事件对象,避免手动运行报错 if (!e) throw new Error("请通过编辑表格触发此函数,不要直接在编辑器中运行"); var sourceTabName = "Workload"; var destinationTabName = "Archive"; var statusColumn = 14; // Column N // 获取当前编辑的标签页 var editedSheet = e.range.getSheet(); // 验证编辑的是目标标签页和目标列 if (editedSheet.getName() === sourceTabName && e.range.getColumn() === statusColumn) { var statusValue = e.value; if (statusValue === "Cancelled" || statusValue === "Complete") { moveRowToDestination(editedSheet, e.range.getRow(), destinationTabName); } } } function moveRowToDestination(sourceSheet, row, destinationTabName) { // 获取整个表格对象 var ss = sourceSheet.getParent(); // 获取目标标签页 var destinationTab = ss.getSheetByName(destinationTabName); if (!destinationTab) throw new Error("未找到名为" + destinationTabName + "的标签页"); // 读取整行数据 var data = sourceSheet.getRange(row, 1, 1, sourceSheet.getLastColumn()).getValues()[0]; // 添加到目标标签页底部 destinationTab.appendRow(data); // 删除原行 sourceSheet.deleteRow(row); }
关键修正点
- 添加事件对象校验:开头判断
!e时抛出明确错误,提示正确触发方式。 - 修正工作表获取逻辑:直接通过
e.range.getSheet()获取当前编辑的标签页,避免混淆表格与标签页的概念。 - 正确获取目标标签页:通过
sourceSheet.getParent()拿到整个表格对象,再从中获取Archive标签页,确保对象层级正确。 - 使用严格相等运算符
===替代==,提升代码严谨性。
内容的提问来源于stack exchange,提问作者user23237041
相关产品推荐
相关产品推荐

