问题描述
我正在尝试找出一个数组公式来计算另一列中列出的类别内的运行余额。
这是一个示例表供参考 https://docs.google.com/spreadsheets/d/1kmitZF6YtARAi2EB0NggbIhKgsb7tLCknsKBTEKycrw/edit?usp=sharing
要求是:
- 要在
Amount
列上计算运行余额 - 应根据
Category
列计算运行余额。 IE。 A 类下的金额应仅计入 A 的运行余额 - 应根据按升序
Date
列排序的值计算运行余额。即使条目可能未排序地出现在工作表中。
任何帮助将不胜感激!
解决方法
最短路径
使用 SUMIFS 函数根据多个条件获取范围的总和。在您的情况下,您有两个:
- 根据类别计算
- 根据日期计算
结果:cell = sumifs(C$2:C,B$2:B,"="&B2,A$2:A,"<="&A2)
语法解释
SUMIFS(sum_range,criteria_range1,criterion1,[criteria_range2,criterion2,...])
-
sum_range - 要求和的范围。
-
criteria_range1 - 根据标准 1 检查的范围。
-
criterion1 - 应用于criterion_range1 的模式或测试。
-
criteria_range2、criteria2、... - [ OPTIONAL ] - 要检查的其他范围和标准。
编辑
如果您需要自动填充新行,您可以将 Spreadsheet Service 用于 Google Apps Script 和 Simple Triggers。
有一个名为 onEdit(e) 的触发器,当用户更改电子表格中任何单元格的值时,它会自动运行。
您可以使用以下代码在每次更改值时更新 Running balance
列。
function onEdit(e) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var last_row = sh.getLastRow()
console.log(last_row)
var formula = '=sumifs(C2:C,B2:B,B2,A2:A,"<="&A2)'
sh.getRange('D2:D'+last_row).setFormula(formula)
}
但是,此代码更新了整个列,覆盖了旧条目的公式。如果您只想更新新条目以获得更高效的代码,您可以使用以下代码。
function onEdit(e) {
var sh = SpreadsheetApp.getActiveSpreadsheet().getActiveSheet()
var last_row = sh.getLastRow()
var last_formula_row = sh.getRange('D1:D').getValues().filter(String).length
var formula = '=sumifs(C$2:C,B' + last_formula_row + ',"<="&A'+ last_formula_row + ')'
sh.getRange('D'+last_formula_row+':D'+last_row).setFormula(formula)
}
我附上你们两个,因为如果没有第一个,第二个可能很难理解。
参考
- SUMIFS:根据多个条件返回范围的总和。
- Spreadsheet Service:允许脚本创建、访问和修改 Google 表格文件。
- Google Apps Script:Google 开发的脚本平台,用于在 Google Workspace 平台上进行轻量级应用开发
- Simple Triggers:当某个事件发生时自动运行一个函数
- onEdit(e) 触发器,当用户更改电子表格中任何单元格的值时自动运行
此方法最多适用于大约 3000 行。不仅如此,我还可以链接到另一个解决方案。尽量减少空行,因为工作表越长,速度就越慢。
=ARRAYFORMULA(ARRAY_CONSTRAIN(MMULT((ROW(B2:B)>=TRANSPOSE(ROW(B2:B)))*(B2:B=TRANSPOSE(B2:B)),N(C2:C)),COUNTA(B2:B),1))
,
慢而短:
=INDEX(IF(A2:A="",MMULT(1*TRANSPOSE(IF((TRANSPOSE(ROW(B2:B))>=
ROW(B2:B))*(B2:B=TRANSPOSE(B2:B)),C2:C,0)),ROW(A2:A)^0)))
快速和高级:
=INDEX(MMULT(1*TRANSPOSE(IF((TRANSPOSE(ROW(
INDIRECT("B2:B"&MAX(ROW(B2:B)*(B2:B<>"")))))>=ROW(
INDIRECT("B2:B"&MAX(ROW(B2:B)*(B2:B<>"")))))*(
INDIRECT("B2:B"&MAX(ROW(B2:B)*(B2:B<>"")))=TRANSPOSE(
INDIRECT("B2:B"&MAX(ROW(B2:B)*(B2:B<>""))))),INDIRECT("C2:C"&MAX(ROW(B2:B)*(B2:B<>""))),ROW(
INDIRECT("B2:B"&MAX(ROW(B2:B)*(B2:B<>""))))^0))
更新:按日期排序:
=INDEX(IF(A2:A="",IFNA(VLOOKUP(A2:A&B2:B,{
INDEX(SORT({A2:A&B2:B,A2:A},2,1),MMULT(1*TRANSPOSE(IF((TRANSPOSE(ROW(B2:B))>=
ROW(B2:B))*(INDEX(SORT({B2:B,1)=
TRANSPOSE(INDEX(SORT({B2:B,1))),INDEX(SORT({C2:C,ROW(B2:B)^0)},0))))