如何识别并处理Google Forms中未作答的问题?
解决Google Forms响应遍历中未作答题型匹配问题
问题核心
遍历Google Forms表单项与响应时,部分题型(如文件上传、线性量表)未作答时,getItemResponses()不会生成对应响应项,导致items数组长度大于itemResponse数组,无法通过索引一一对应,无法定位未作答的问题。
解决方案思路
放弃索引直接匹配逻辑,通过表单项ID建立响应映射:
- 将已提交响应转换为以item ID为键的对象,快速查找对应问题的响应
- 遍历每个表单项时,用item ID在映射对象中查找响应,找不到则判定为未作答
- 针对不同题型单独处理响应展示逻辑,覆盖未作答场景
重构后的完整代码
var form = FormApp.getActiveForm(); var title = form.getTitle(); var items = form.getItems(); var responseSet = form.getResponses(); var lastResponse = responseSet.length - 1; var itemResponses = responseSet[lastResponse].getItemResponses(); // 构建响应映射:以item ID为键,存储对应的ItemResponse var responseMap = {}; itemResponses.forEach(function(resp) { responseMap[resp.getItem().getId()] = resp; }); var table = []; title = title + '\n'; var docTitle = noteBody.appendParagraph(title); docTitle.setAttributes(titleStyle); for (var i = 0; i < items.length; i++) { var item = items[i]; var itemType = item.getType(); var itemTitle = item.getTitle(); var thisResponse = "[no response]"; var currentResponse = responseMap[item.getId()]; // 通过ID匹配响应 // 跳过非题型元素 if (itemType === FormApp.ItemType.IMAGE || itemType === FormApp.ItemType.PAGE_BREAK || itemType === FormApp.ItemType.SECTION_HEADER || itemType === FormApp.ItemType.VIDEO) { continue; } // 处理网格类题型(Checkbox Grid/Grid) if (itemType === FormApp.ItemType.CHECKBOX_GRID || itemType === FormApp.ItemType.GRID) { table.push([itemTitle.toUpperCase()]); var gridItem; if (itemType === FormApp.ItemType.CHECKBOX_GRID) { gridItem = item.asCheckboxGridItem(); } else { gridItem = item.asGridItem(); } var rows = gridItem.getRows(); if (currentResponse) { var gridResponse = currentResponse.getResponse(); for (var n = 0; n < rows.length; n++) { var rowTitle = " " + rows[n].toString(); var rowAnswer = gridResponse[n] ? gridResponse[n].toString() : "[no response]"; table.push([rowTitle, rowAnswer]); } } else { // 整个网格未作答 table.push([" [no response]"]); } continue; } // 处理线性量表题型 if (itemType === FormApp.ItemType.LINEAR_SCALE) { if (currentResponse) { thisResponse = currentResponse.getResponse().toString(); } table.push([itemTitle, thisResponse]); continue; } // 处理文件上传题型 if (itemType === FormApp.ItemType.FILE_UPLOAD) { if (currentResponse) { var files = currentResponse.getResponse(); thisResponse = files.map(function(file) { return file.getName(); // 可根据需求替换为文件URL等信息 }).join(", "); } table.push([itemTitle, thisResponse]); continue; } // 处理其他常规题型(单选、多选、文本等) if (currentResponse) { var rawResponse = currentResponse.getResponse(); // 将数组类型响应(如多选)转为逗号分隔字符串 thisResponse = Array.isArray(rawResponse) ? rawResponse.join(", ") : rawResponse; // 空字符串视为未作答 if (thisResponse === "") { thisResponse = "[no response]"; } } table.push([itemTitle, thisResponse]); }
代码说明
- 响应映射构建:通过
responseMap绑定ItemResponse与对应item ID,彻底解决索引不匹配问题 - 题型分支处理:针对线性量表、文件上传、网格题等特殊题型单独适配,确保未作答时正确标记
- 常规题型兼容:自动将多选等数组类型响应转为字符串,空响应统一标记为
[no response]
内容的提问来源于stack exchange,提问作者Raffi
相关产品推荐
相关产品推荐

