我使用谷歌电子表格来跟踪每个供应商的应付账款。电子表格中每个供应商都有一张表。简化的sheet看起来像这样:
当我收到新发票时,会在
Credit
列中输入金额;当我发放付款时,会在 Debit
列中输入金额。我在 AC Payable
列中跟踪运行总计。我通过在 AC Payable
列的每个单元格中使用公式来实现此目的(下面的示例来自单元格 E4
):
=IF(
ISNUMBER(INDIRECT(ADDRESS(ROW()-1,COLUMN()))),
INDIRECT(ADDRESS(ROW()-1,COLUMN()))+C4-D4,
C4-D4
)
逻辑很简单。第
n
行的运行总计由以下公式计算:
AC Payable(n - 1) + Credit(n) - Debit(n)
此设置工作正常,只是我必须将公式拖到新添加的行中。有没有办法通过使用
ARRAYFORMULA
来实现这一目标?
PS:我找到了解决方案:
= ARRAYFORMULA(
SUMIF(
ROW(C3:C),
"<="&ROW(C3:C),
C3:C)
-
SUMIF(
ROW(D3:D),
"<="&ROW(D3:D),
D3:D
)
)
我觉得这是一个次优的(原始工作表可以追溯到 2018 年。它有很多行)解决方案,因为在每一行中,它都会计算直到当前行的
Debit
和 Credit
列的总和然后从 Debit
列的总和中减去 Credit
列的总和。
我期待一个解决方案,该解决方案将利用前一行中可用的运行总计,而不是重做每行的整个计算。
=ARRAYFORMULA(QUERY(QUERY(MMULT(TRANSPOSE((SEQUENCE(COUNTA(A3:A)*2)<=
SEQUENCE(1, COUNTA(A3:A)*2))*FLATTEN(INDIRECT("C3:D"&COUNTA(A3:A)+ROW(A3)-1)*{1, -1})),
SEQUENCE(COUNTA(A3:A)*2, 1, 1, 0)), "offset 1", ), "skipping 2", ))
技能:
它基于标准 MMULT 运行/累积总计/总和公式:
=ARRAYFORMULA(MMULT(TRANSPOSE((ROW(B1:B6)
<=TRANSPOSE(ROW(B1:B6)))*B1:B6), SIGN(B1:B6)))
但是有一个修改,因为总共有 2 列
我们使用实际数据计数序列乘以 2 来代替
ROW(B1:B6)
(因为您有 2 列):
SEQUENCE(COUNTA(A3:A)*2)
我们再次使用而不是
TRANSPOSE(ROW(B1:B6))
:
SEQUENCE(1, COUNTA(A3:A)*2)
这些作品的组合:
=ARRAYFORMULA(TRANSPOSE((SEQUENCE(COUNTA(A3:A)*2)<=SEQUENCE(1, COUNTA(A3:A)*2))))
将产生一个矩阵,如:
这就是它在行数很多时死掉的原因,因为虽然您可能认为如果两列中只有 1500 行,那么公式将仅适用于
1500*2=3000
虚拟单元格,但实际上 MMULT 公式会处理 (1500*2)*(1500*2)=9000000
虚拟细胞。不过,值得注意的是,如果小规模部署,这个 MMULT fx 会很棒。
接下来,我们使用:
代替
*B1:B6
*FLATTEN(INDIRECT("C3:D"&COUNTA(A3:A)+ROW(A3)-1)*{1, -1}))
例如。使用 INDIRECT,我们只采用 C3:D 的“有效”范围,在您的示例表中只是 C3:D5,我们将 C 列乘以
1
,将 D 列乘以 -1
来模拟减法,然后我们将两列扁平化为一列单列。 +ROW(A3)-1
部分只是一个偏移量,因为你从第3行开始
标准 RT fx 的最后一部分 -
SIGN(B1:B6)
被替换为一列:
SEQUENCE(COUNTA(A3:A)*2, 1, 1, 0)
然后我们将内部 QUERY 的输出偏移 1,因为我们对减法后的总计感兴趣,最后我们使用
skipping 2
这意味着我们过滤掉每个第二个值 - 同样,我们对 D 列减去后的总计感兴趣。
=ARRAYFORMULA(
SUMIF(SEQUENCE(COUNTA(A3:A)), "<="&SEQUENCE(COUNTA(A3:A)), INDIRECT("C3:C"&COUNTA(A3:A)))-
SUMIF(SEQUENCE(COUNTA(A3:A)), "<="&SEQUENCE(COUNTA(A3:A)), INDIRECT("D3:D"&COUNTA(A3:A))))
技能:
=ARRAYFORMULA(
IF(ISBLANK(A2:A),,
MMULT(TRANSPOSE((ROW(C2:C)<=TRANSPOSE(ROW(C2:C)))*C2:C),SIGN(C2:C))-
MMULT(TRANSPOSE((ROW(D2:D)<=TRANSPOSE(ROW(D2:D)))*D2:D),SIGN(D2:D))))
MMULT 的另一种替代方案:
=INDEX(QUERY(FLATTEN(QUERY(QUERY(TRANSPOSE(QUERY(QUERY(TRANSPOSE(
(SEQUENCE(COUNTA(A3:A)*2)<=SEQUENCE(1, COUNTA(A3:A)*2))*
FLATTEN(INDIRECT("C3:D"&COUNTA(A3:A)+ROW(A3)-1)*{1, -1})),
"offset 1", ), "skipping 2", )), "select "&QUERY(
"sum(Col"&SEQUENCE(COUNTA(A3:A))&"),",, 9^9)&"' '"),
"offset 1", )), "where Col1 is not null", ))
但是,LTE (
<=
) 10M 单元的限制不会让您在您的案例中使用超过 1581 行,或者在标准累积和案例中使用超过 3162 行
(1581 rows * 2 columns) raised on 2nd power < 10 million cells
(1581*2)^2 = 9998244
C 列总计的计算公式:-
={"Running Total";
ArrayFormula(if(C2:C="",,scan(0,C2:C,lambda(a,v,(a+v)))))
}
如果您希望结果显示在空白行上,请删除 IF 语句。