【问题标题】:Google Sheets - ArrayFormula Calculate Difference with Previous Cells谷歌表格 - ArrayFormula 计算与先前单元格的差异
【发布时间】:2014-06-03 16:53:35
【问题描述】:

使用 Google 电子表格,我希望能够将公式放入标题列,这样我就不必手动填充行(我有一个每天自动添加值的 Google 脚本)。我知道执行此操作的常用方法是使用 ArrayFormula。

我有几个公式想像这样设置,但现在我试图找出当前单元格和上一行单元格之间的差异。

这是它应该做的:

Bal Dif 0 20 20 20 0 21 1 22 1

我能用 ArrayFormula 得到的最接近的是:

Bal Dif 0 20 20 0 20 1 21 1 22 1

这是使用公式:=arrayformula(D2:D-D1:D)。 就好像我需要=arrayformula(D1:D-D0:D) 但显然这是无效的。

有什么好的方法可以获取实际具有新值的行上的差值?

谢谢,希望有人能帮忙。

【问题讨论】:

    标签: google-sheets array-formulas


    【解决方案1】:

    我找到了另一种适合我需要的解决方案,这里没有提到计算同一列中一个值与其前一个值之间的差异而无需手动复制(又名:使用 arrayformula 函数)的问题。

    假设您的值位于 B 列并从第 3 行开始:ARRAYFORMULA(IFERROR(IF(ARRAY_CONSTRAIN(B3:B,COUNTA(B3:B),1)>ARRAY_CONSTRAIN(B2:B,COUNTA(B3:B),1),ARRAY_CONSTRAIN(B3:B,COUNTA(B3:B),1)-ARRAY_CONSTRAIN(B2:B,COUNTA(B3:B),1),NA()),NA()))

    这里的关键是使用ARRAY_CONSTRAIN([needed_range_for_calculation],[number_of_non_blank_values],1) 而不是过滤(我认为这是资源消耗和可读性较差)。

    如果出现错误(例如:B2 中的 NaN)或之前的值大于当前值,上述公式将返回 #N/A 值。如果允许负差异,它将变为:ARRAYFORMULA(IFERROR(ARRAY_CONSTRAIN(B3:B,COUNTA(B3:B),1)- ARRAY_CONSTRAIN(B2:B,COUNTA(B3:B),1),NA()))

    如果您的公式写在第一行,@user3912079 在电子表格中发布的使用IF(row(B:B)=1;NA();([your formula])) 检查它是否是第一行的解决方案应该可以正常工作。

    【讨论】:

      【解决方案2】:

      其实我不太明白你为什么不直接写到“E2”单元格:

      D2-D1(假设您的值在 D 列中),然后只需向下拖动公式,直到您有值。 (我知道您将在 D 列中有越来越多的值,但您可以添加一个 if 条件来检查该特定 D 单元格是否为空,如果不是,则计算前一行的减法。)

      也许这不是你要找的(那么抱歉,我误解了这个问题),但无论如何我都会这样做。

      希望对您有所帮助。

      更新:

      了解真正的问题后,我会使用这个功能:

      =arrayformula(if(isblank(A3:A100),"",filter(A3:A100,A3:A100>-1)-filter(A2:A99,A2:A99>-1 )))

      假设你的数据在 A 列(并且 A 列中没有任何值小于 0!),将其写入单元格 B3,它将​​产生 diff-s。

      解释:看函数的最后一部分——...filter(A3:A100,A3:A100>-1)-filter(A2:A99,A2:A99>-1) - 这只是两个查询,它们将返回两个大小相等的列表。第一个来自 A3-A100,第二个来自 A2-A99。两个列表中的元素必须相等,这一点很重要。 (在这种情况下,两个列表中都有 98 个元素)。并且两个列表之间有一个减法 (-) 符号,因此如果我们将 ARRAYFORMULA 放在这两个列表之前,它将对列表中的每个“对”进行减法。列表的第一个元素是“A3”和“A2”,因此 A3-A2 将是 B3 的值。列表的第二个元素是“A4”和“A3”,因此 A4-A3 将转到 B4,依此类推。所以基本上我们完成了:

      =arrayformula(filter(A3:A100,A3:A100>-1)-filter(A2:A99,A2:A99>-1))

      主要部分已经完成,虽然额外的 IF 的目的是如果当前 A 字段为空,则我们写入一个空字符串 (""),否则我们计算减法,如上所述。

      所以再次完整的功能:

      =arrayformula(if(isblank(A3:A100),"",filter(A3:A100,A3:A100>-1)-filter(A2:A99,A2:A99>-1)))

      正如我之前所说,此函数假定 A 列中只有非负数。如果不是这种情况,只需将过滤条件 (-1) 重写为一个非常小的负数。 (如“-99999999”)

      希望对你有帮助。

      【讨论】:

      • 谢谢。它可能归结为使脚本以某种方式自动填充公式。本专栏是我最不担心的,因为我想使用的其他专栏之一使用 ArrayFormula 获取循环引用。
      • 现在,我明白你想做什么了。所以以前我没有得到这个问题。但是现在,让我们使用这个函数: =arrayformula(if(isblank(A3:A100),"",filter(A3:A100,A3:A100>-1)-filter(A2:A99,A2:A99>-1) )) - 假设您的数据在您的 A 列中。 (如果它在 D 列中,只需将“A”-s 替换为“D”-s。我会尽快编辑我的原始帖子。
      • @zolley 我想完全按照您在第一段中描述的那样做。我有一个简单的计算,可以使用“蓝框”手动将其拖下。但是,我希望在添加新行时自动完成此操作,因为新行自动来自 Google From。有没有简单的方法可以做到这一点?对于这么简单的事情,使用巨大的 ARRAYFORMULA 似乎是大材小用。
      【解决方案3】:

      我发现之前的答案有点复杂。

      假设,A2:A 包含数据,以下内容更简短:

      =ARRAYFORMULA(IF(A2:A="", "", IF(ROW(A2:A)=ROW(A2), "", A2:A-A1:A)))
      

      这会生成下表:

      Bal Diff
      0 ##Formula here##
      20 20
      20 0
      21 1
      22 1

      说明:

      第一个IF(A2:A="") 避免填满整个列。它还避免了片材的膨胀。如果没有该检查,工作表会在后台无限增长。当页面大小达到限制时会触发错误。

      第二个IFROW(A2:A)=ROW(A2) 处理第一个数据行,如果我们需要第一行的其他内容,我们可以更改此行。

      最后一部分 (A2:A-A1:A) 计算差异。在大多数其他计算中,Google 表格抱怨ARRAYFORMULA 定义中的大小不匹配。在这种情况下,它可以正常工作,尽管A2:A 的大小小于A1:A

      如果让我们把公式放在B3,公式可以更简单:

      =ARRAYFORMULA(IF(A3:A="", "", A3:A-A2:A))
      

      注意:对于知道IFS 语句的人来说,它在这里不起作用。 IFS 公式将失败并出现 size mismatch 错误。

      【讨论】:

        【解决方案4】:

        我迟到了吗? 我也到达了查看下一行的数组公式。为什么不在数组中查看下一行的值,这样您就可以在同一行中同时获得新值和差异。

        https://docs.google.com/spreadsheets/d/1mR2zI1KKqBtj0LGgO_keWyVbWRqotsLTiak40BNXI8E/edit?usp=sharing

        评论:我使用了这些数组公式,它们在两个地方查找下一行。在创建公式时,工作表都超过 30000 行,但是可以删除,一切正常。

        【讨论】:

          猜你喜欢
          • 2014-12-18
          • 2017-11-12
          • 1970-01-01
          • 2021-03-29
          • 2020-05-23
          • 1970-01-01
          • 2022-10-19
          • 2023-02-03
          • 1970-01-01
          相关资源
          最近更新 更多