Google Apps Script用for循环发HTML模板邮件出现ReferenceError如何解决
问题修复方案
错误原因
- 函数嵌套导致的闭包问题:你将
getEmailHtml函数定义在for循环内部,加上用var声明的循环变量i没有块级作用域,所有循环迭代共享同一个i引用,函数执行时i已经指向非预期的索引,导致row相关取值报错。 - 数组遍历方式不规范:
for...in语法是为遍历对象属性设计的,用于数组遍历容易出现非预期的额外属性,也会加剧作用域问题。 - 全局变量执行逻辑风险:表格读取逻辑放在全局作用域,脚本加载时就会执行,而非调用
sendEmail时才读取最新数据,可能出现数据不一致。
修复后的代码
function sendEmail() { // 把表格读取逻辑移入函数内,仅在调用发邮件时读取最新数据 var sheet = SpreadsheetApp.getActive().getSheetByName('DB.charters'); var startRow = 3 ; var numRows = 3 ; var dataRange = sheet.getRange(startRow,1,numRows,15); var boatData = dataRange.getValues(); // 把HTML生成函数移到循环外,接收行数据作为参数,避免依赖外部变量 function getEmailHtml(rowData) { var htmlTemplate = HtmlService.createTemplateFromFile("emailTempWorkOrder.html"); htmlTemplate.boats = rowData; console.log(rowData); var htmlBody = htmlTemplate.evaluate().getContent(); return htmlBody; } // 改用普通for循环遍历数组,逻辑更清晰 for (var i = 0; i < boatData.length; i++) { var row = boatData[i]; var htmlBody = getEmailHtml(row); MailApp.sendEmail({ to: "bmsbreaux@gmail.com", subject: `Vessel Charter: ${row[1]} -`, htmlBody: htmlBody, }); } console.log('Ran sendEmailWorkOrder(), sent emails'); }
改动说明
- 把表格读取逻辑移入
sendEmail函数内部,保证每次发邮件都读取表格最新数据,避免全局变量污染 - 将
getEmailHtml移到循环外部,改为接收当前行数据作为入参,完全避免闭包捕获外部变量导致的取值错误 - 把
for...in遍历换成普通for循环,适配数组遍历场景 - 去掉了函数内部对外部循环变量
i的依赖,直接传入行数据取值,逻辑更直观
内容的提问来源于stack exchange,提问作者Brittan M. S. Breaux
相关产品推荐
相关产品推荐

