如何用公式或App Script将Google表单响应多列数据合并至单列?
实现Google Sheets多列转单列并支持自动更新(公式+脚本方案)
你已通过ARRAYFORMULA+FILTER完成db_Responses表A-C列的单列整理,且支持表单新提交自动同步。针对D-S列的多列转单列需求,以下是两种可行实现方案:
一、公式实现方案
核心逻辑
借助FLATTEN快速将多列数据转为单列,搭配FILTER过滤无效行,再用ARRAYFORMULA实现自动填充,完全匹配你现有A-C列的更新逻辑。
具体公式
在db_Responses表的D2单元格输入以下公式(D1手动填写对应表头):
=ARRAYFORMULA(FLATTEN(FILTER('Form Responses 3'!D2:S, 'Form Responses 3'!B2:B<>"")))
公式说明
FLATTEN:将指定的D2:S多列区域按行优先顺序转为单列FILTER:过滤掉Form Responses表中B列为空的行,与A-C列过滤规则保持一致ARRAYFORMULA:让公式自动覆盖整列,新表单提交后数据会自动更新
若需要按列优先转单列(先列内所有行,再下一列),可改用以下公式:
=ARRAYFORMULA(QUERY(FLATTEN(TRANSPOSE(FILTER('Form Responses 3'!D2:S, 'Form Responses 3'!B2:B<>""))), "where Col1 is not null"))
二、App Script实现方案
如果需要自定义排序、额外数据清洗等复杂逻辑,可通过脚本实现更灵活的同步:
脚本代码
打开Google Sheets,点击「扩展程序」→「Apps Script」,粘贴以下代码:
function syncFormResponsesToDb() { const ss = SpreadsheetApp.getActiveSpreadsheet(); const formSheet = ss.getSheetByName('Form Responses 3'); const dbSheet = ss.getSheetByName('db_Responses'); // 过滤出B列非空的有效行 const validRows = formSheet.getDataRange().getValues().filter(row => row[1] !== ""); // 提取D-S列数据并转为单列(数组索引从3到18,对应原表D到S列) const flattenedData = validRows.map(row => row.slice(3, 19)).flat(); // 清空db表D列旧数据(保留表头) dbSheet.getRange(2, 4, dbSheet.getLastRow() - 1, 1).clearContent(); // 写入新数据 if (flattenedData.length > 0) { dbSheet.getRange(2, 4, flattenedData.length, 1).setValues(flattenedData.map(val => [val])); } } // 创建表单提交触发事件,实现自动同步 function createSubmitTrigger() { ScriptApp.newTrigger('syncFormResponsesToDb') .forSpreadsheet(SpreadsheetApp.getActiveSpreadsheet()) .onFormSubmit() .create(); }
使用步骤
- 保存脚本后,先执行一次
createSubmitTrigger函数,完成授权后会自动创建表单提交触发规则 - 后续每次表单提交,脚本会自动同步有效数据到db_Responses表的D列
方案对比
- 公式方案:轻量无需授权,适合简单转列需求,完全适配现有自动更新逻辑
- 脚本方案:支持复杂自定义处理,灵活性更高,但需要授权配置触发事件
内容的提问来源于stack exchange,提问作者Lyndon Broz Tonelete
相关产品推荐
相关产品推荐

