You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

仅在必要时拆分Google Form单行响应至独立工作表多行的脚本问题

Google Apps Script 问题:仅当宠物信息非空时生成对应行

背景

某非营利组织使用Google Form作为客户登记表,客户可填写最多4只宠物的信息,每只宠物需单独处理,因此需将每只宠物信息拆分为独立行存入对应工作表。

现有问题

编写的copyTo函数尝试仅当宠物信息非空时,在"Responses"表新增合并主人与对应宠物信息的行,但当前每次都会生成4行——即使部分宠物信息为空,后两行仅含主人信息,宠物信息为空。

原代码

function copyTo(destinationSSId) {
    // Open source SS at tab named "Data"
    let dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
    // Open destination SS at tab named "Responses"
    let responseSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Responses");
    // Get source values
    let templateValues = dataSheet.getRange(dataSheet.getLastRow(), 1, 1, 14).getValues();
    let c1Values = dataSheet.getRange(dataSheet.getLastRow(), 15, 1, 7).getValues();
    let c2Values = dataSheet.getRange(dataSheet.getLastRow(), 22, 1, 7).getValues();
    let c3Values = dataSheet.getRange(dataSheet.getLastRow(), 29, 1, 7).getValues();
    let c4Values = dataSheet.getRange(dataSheet.getLastRow(), 36, 1, 7).getValues();

    // Set first row
      responseSheet.getRange(responseSheet.getLastRow() + 1, 2, 1, 14).setValues(templateValues);
      responseSheet.getRange(responseSheet.getLastRow(), 16, 1, 7).setValues(c1Values)

    // Set second row if applicable
    if (c2Values !==""){
      responseSheet.getRange(responseSheet.getLastRow() + 1, 2, 1, 14).setValues(templateValues)
      responseSheet.getRange(responseSheet.getLastRow(), 16, 1, 7).setValues(c2Values)
    } 
    // Set third row if applicable
    if (c3Values !==""){
      responseSheet.getRange(responseSheet.getLastRow() + 1, 2, 1, 14).setValues(templateValues)
      responseSheet.getRange(responseSheet.getLastRow(), 16, 1, 7).setValues(c3Values)
    }
    // Set fourth row if applicable 
    if (c4Values !==""){
      responseSheet.getRange(responseSheet.getLastRow() + 1, 2, 1, 14).setValues(templateValues)
      responseSheet.getRange(responseSheet.getLastRow(), 16, 1, 7).setValues(c4Values)
    } 
} 

错误原因

  1. 数组与字符串的错误比较:getValues()返回的是二维数组(比如c2Values是[[null, null, ...]]),直接和空字符串""比较时,由于类型不同,判断结果永远为true,导致空宠物信息的分支也会执行新增行操作。
  2. 第一行未做判断:原代码直接写入第一行宠物信息,即使c1Values为空也会生成一行仅含主人信息的记录。

修改方案

1. 新增空值判断辅助函数

编写函数检查宠物信息数组是否包含有效内容(即不全为空/ null):

function hasPetData(petValues) {
  // 展开二维数组为一维,检查是否有非空/非null的元素
  return petValues[0].some(cell => cell !== "" && cell !== null);
}

2. 重构代码逻辑

将所有宠物信息存入数组循环处理,避免重复代码,统一判断每一组信息是否有效:

修改后的完整代码:

function copyTo(destinationSSId) {
    const dataSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Data");
    const responseSheet = SpreadsheetApp.getActiveSpreadsheet().getSheetByName("Responses");
    const lastRow = dataSheet.getLastRow();
    
    // 读取主人信息(转为一维数组,方便后续合并)
    const templateValues = dataSheet.getRange(lastRow, 1, 1, 14).getValues()[0];
    // 读取4组宠物信息,转为一维数组的集合
    const petGroups = [
        dataSheet.getRange(lastRow, 15, 1, 7).getValues()[0],
        dataSheet.getRange(lastRow, 22, 1, 7).getValues()[0],
        dataSheet.getRange(lastRow, 29, 1, 7).getValues()[0],
        dataSheet.getRange(lastRow, 36, 1, 7).getValues()[0]
    ];

    // 遍历每组宠物信息,仅当有有效数据时写入
    petGroups.forEach(petData => {
        if (hasPetData([petData])) {
            // 构建完整行数据:第1列留空,填充主人信息到第2-15列,宠物信息到第16-22列
            const fullRow = new Array(1).fill("");
            fullRow.splice(1, 14, ...templateValues);
            fullRow.splice(15, 7, ...petData);
            // 写入一行数据
            responseSheet.appendRow(fullRow);
        }
    });
}

function hasPetData(petValues) {
    return petValues[0].some(cell => cell !== "" && cell !== null);
}

关键改进点

  • 使用appendRow()简化行写入操作,无需手动计算行号,避免行号计算错误
  • 将getValues()返回的二维数组转为一维数组,更方便进行数据合并与空值判断
  • 通过some()方法高效检查宠物信息组中是否存在非空/非null的有效内容
  • 用循环遍历4组宠物信息,大幅减少重复代码,提升可维护性
  • 统一对所有宠物信息组做非空判断,包括第一组,彻底解决空行问题

内容的提问来源于stack exchange,提问作者Erin

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.11 13:24:53