【问题标题】:Google Sheets switch has mismatched range sizesGoogle 表格开关的范围大小不匹配
【发布时间】:2021-07-17 19:18:15
【问题描述】:

我开发了一个在过去 2 年中运行良好的 Google 表格。现在,它突然停止运行,提供以下错误:“SWITCH 的范围大小不匹配。预期的行数:1,列数:1。实际行数:number_of_rows_in_sheet,列数:1。”

基本上,该工作表包含需要以特定时间间隔检查的项目列表(J=每天,M=每月,S=每学期,A=每年)。检查项目的用户勾选一个复选框,这会导致 onEdit 脚本运行,将 lastChecked 的日期更新为今天。 根据间隔,公式计算 nextCheck 的截止日期。此公式在整个列的 ArrayFormula 中。

如前所述,系统直到几周前都可以正常工作,并且在不使用 ArrayFormula 时仍然可以正常工作,但我更喜欢使用 ArrayFormula(用户更容易添加新行)。

功能副本可用here。工作表 A 有 ArrayFormula,B 没有,C/D 为空,但通常遵循 A/B 结构。

错误来自包含此公式的单元格(单元格 G2):

=ArrayFormula(IF(E2:E="","", SWITCH(D2:D, "A", DATE(YEAR(E2:E)+IF(C2:C="",1,C2:C),MONTH(E2:E),DAY(E2:E)), "M", DATE(YEAR(E2:E),MONTH(E2:E)+IF(C2:C="",1,C2:C),DAY(E2:E)), "S", DATE(YEAR(E2:E),MONTH(E2:E)+IF(C2:C="",6,C2:C *6),DAY(E2:E)), "J", DATE(YEAR(E2:E),MONTH(E2:E),DAY(E2:E)+IF(C2:C="",1,C2:C)),"","")))

更新时间戳的代码:

function onEdit(e) {  //On edit...
  const sheet = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet();
  const changedCell = e.range;  //Saves the range of the modified cell.
  const sheetName = sheet.getName();
  const sheetsToWatch = ['A', 'B', 'C', 'D'];
  
  if (sheetsToWatch.includes(sheetName)) {
    if(changedCell.getColumn() === 6 && changedCell.isChecked()) {   //If cell is in col 6 (F) and checked
      let newDateRange = sheet.getRange(changedCell.getRow(), 5);
      newDateRange.setValue(new Date());   //Set the current timestamp in column 5 (E) at the same row as modified cell
      
      changedCell.uncheck();               //Remove checkmark from modified cell
    }
  }
}

这是我的第一篇文章,如果我忘记了任何有用的信息,请告诉我。 提前致谢。

【问题讨论】:

    标签: google-apps-script google-sheets


    【解决方案1】:

    Google 最近对数组公式上下文中switch() 的行为进行了重大更改。要解决此问题,请尝试使用数组而不是文字作为 case 参数,如下所示:

    =arrayformula( 
      switch( 
        D2:D, 
        iferror(D2:D/0, "A"), eomonth(E2:E, if(C2:C, C2:C, 1) * 12 - 1) + day(E2:E), 
        iferror(D2:D/0, "S"), eomonth(E2:E, if(C2:C, C2:C, 1) * 6 - 1) + day(E2:E), 
        iferror(D2:D/0, "M"), eomonth(E2:E, if(C2:C, C2:C, 1) - 1) + day(E2:E), 
        iferror(D2:D/0, "J"), E2:E + if(C2:C, C2:C, 1), 
        iferror(1/0) 
      ) 
    )
    

    我希望这种解决方法能够在未来证明 Google 可能会解决 switch() 的潜在问题。

    【讨论】:

    • 感谢您的回答。尽管它有效,但我无法理解为什么 iferror() 会修复它,以及为什么 if(D2:D, "A") 不能修复它。您还提到了一个数组而不是文字,但我没有看到数组在您的示例中发挥作用。你能详细说明一下吗?
    • arrayformula() 包装器中,iferror(D2:D/0, "A") 将在每一行返回“A”。如果您愿意,可以使用if(len(D2:D), "A", "A")left("A" & D2:D) 代替iferror()if(D2:D, "A") 的问题在于它会在某些行上返回“A”,而在其他行上会返回 FALSE
    • 好的,既然iferror(D2:D/0)总是一个错误,它总是会返回A。但是,为什么if(1, "A") 不起作用?是因为它不依赖于另一个细胞吗?我不是想避免iferror(),而是想了解为什么一个有效而另一个无效。
    • if(1, "A") 不返回数组,它返回文字 "A"。对于大多数函数,您需要引用一个数组来获取数组结果,即使在 arrayformula() 包装器中也是如此。 iferror() 也是如此。这是我选择的模式,但显然还有很多其他模式可供您使用。
    • 啊我明白了;该函数本质上需要一个数组来返回一个数组,这是arrayformula 所必需的,这是有道理的。感谢您的帮助。
    【解决方案2】:

    您可能需要考虑使用IFS() 而不是SWITCH() 作为解决方法:

    细胞 G2 公式:

    =ArrayFormula(IF(E2:E="","", IFS(D2:D="A", DATE(YEAR(E2:E)+IF(C2:C="",1,C2:C),MONTH(E2:E),DAY(E2:E)), D2:D="M", DATE(YEAR(E2:E),MONTH(E2:E)+IF(C2:C="",1,C2:C),DAY(E2:E)), D2:D="S", DATE(YEAR(E2:E),MONTH(E2:E)+IF(C2:C="",6,C2:C *6),DAY(E2:E)), D2:D="J", DATE(YEAR(E2:E),MONTH(E2:E),DAY(E2:E)+IF(C2:C="",1,C2:C)))))
    

    我没有找到您遇到此类错误的任何具体根本原因。我怀疑它与DATE()SWITCH()ARRAYFORMULA() 组合有关。

    【讨论】:

      猜你喜欢
      • 2019-09-29
      • 1970-01-01
      • 1970-01-01
      • 2017-03-26
      • 1970-01-01
      • 1970-01-01
      • 2022-07-15
      • 1970-01-01
      • 2017-11-14
      相关资源
      最近更新 更多