Google Apps Script:如何用for循环+if语句输出数组非空字段?
问题修复:Google Apps Script循环未执行的问题
问题背景
我有一个Google表单,提交的响应会存储到Google Sheet中。表单提交后,会利用Sheet中的存储值生成邮件,邮件正文需包含表单所有必填字段以及已填写的非必填字段。尝试使用for循环遍历数组,结合if语句仅输出含有数据的字段,但for循环未进入执行,添加else语句也无任何输出。
错误分析
从代码和日志来看,核心问题出在以下几点:
- 循环条件错误:原代码中
for (var i = 5; i < filterData[0][i]; i++)的条件完全错误,filterData是一维数组,不存在filterData[0][i],且循环终止条件应该基于数组长度,而非元素值。 - 数组维度理解错误:
recentResponse.getDisplayValues()返回二维数组,recentResponse.filter(Boolean).forEach(...)中,value是一维数组,后续filterData = value.filter(String)得到的也是一维数组,不能用filterData[0][i]访问元素。 - Logger.log的错误用法:
var businessName = Logger.log(recentResponse[0][0])这种写法会把Logger.log的返回值(undefined)赋值给变量,完全没有意义,应该先赋值再单独打印。 - 商品项遍历逻辑错误:商品名称和数量是成对出现的,遍历应该以步长2推进,而非步长1。
修正后的代码
main函数
function main() { // 访问表单响应对应的Sheet var formResponses = getSheetById(1693762938); // 获取最新一行的响应数据(从第2列开始,跳过时间戳列) var recentResponse = formResponses.getRange(formResponses.getLastRow(), 2, 1, formResponses.getLastColumn() - 1).getDisplayValues()[0]; // 提取必填字段 var businessName = recentResponse[0]; var receiptEmail = recentResponse[1]; var receipientName = recentResponse[2]; var receipientAddress = recentResponse[3]; var shippingMethod = recentResponse[4]; // 打印必填字段(用于调试) Logger.log(businessName); Logger.log(receiptEmail); Logger.log(receipientName); Logger.log(receipientAddress); Logger.log(shippingMethod); // 准备要放入邮件的商品列表 var itemsToEmail = []; // 遍历商品项(从索引5开始,步长2,对应名称+数量的成对字段) for (var i = 5; i < recentResponse.length; i += 2) { var itemName = recentResponse[i]; var itemQty = recentResponse[i + 1] || 0; // 数量为空时默认0 if (itemName.trim() !== '') { // 仅处理有名称的商品 var itemText = itemName + ", Qty = " + itemQty; Logger.log(itemText); itemsToEmail.push(itemText); } } // 这里可以添加生成邮件的逻辑,使用itemsToEmail填充email.html模板 // 示例: // var htmlBody = HtmlService.createTemplateFromFile('email.html') // .evaluate() // .getContent(); // MailApp.sendEmail({ // to: receiptEmail, // subject: '新订单确认', // htmlBody: htmlBody // }); }
getSheetById函数(保留原逻辑,仅添加优化)
function getSheetById(sheet_id) { // 访问当前工作簿 var wb = SpreadsheetApp.getActiveSpreadsheet(); // 获取所有工作表 var sheets = wb.getSheets(); var sheetName = ''; // 遍历工作表查找对应ID for(var i in sheets){ // 修复:添加var声明i,避免全局变量污染 if(sheets[i].getSheetId() == sheet_id) { sheetName = sheets[i].getSheetName(); break; // 找到后直接跳出循环,提升效率 } } // 返回对应的工作表 return wb.getSheetByName(sheetName); }
修正后日志效果
执行后会打印所有非空的商品项,例如:
9:50:47 PM Notice Execution started 9:50:56 PM Info Happy Days Cafe 9:50:56 PM Info myname@gmail.com 9:50:56 PM Info First Last 9:50:56 PM Info 123 Hillbilly Drive 9:50:56 PM Info Pick up 9:50:56 PM Info Apple Pie, Qty = 1 9:50:56 PM Info Half Baked, Qty = 9:50:49 PM Notice Execution completed
关键修改说明
- 直接提取
recentResponse为一维数组:getDisplayValues()[0]简化后续元素访问。 - 修正循环条件:基于数组长度
recentResponse.length,步长设为2,匹配商品名称+数量的成对结构。 - 移除错误的
Logger.log赋值,改为先赋值再打印。 - 添加
trim()判断商品名称是否为空,避免处理空白字符串。 - 在
getSheetById中添加break提升查找效率,修复变量未声明的问题。
内容的提问来源于stack exchange,提问作者Joe Coyle
相关产品推荐
相关产品推荐

