使用 VBA 的特定小计

Specific subtotals using VBA

以上是我从数据库中提取的输入数据示例。 A 列有多个级别(命名为 L1、L2、L3、L4、L5)。 B 列有值。它的运作方式是, L2 = 它上面的所有 L1 的总和,直到遇到上面的另一个 L2。 L3 = 上面所有 L2 的总和,直到遇到上面的另一个 L3。

L4 类似。最终级别是 L5,它具有列中所有 L4 的总和。

此外,有时会有一个独立的 L2(没有可用的 L1 分解详细信息),必须按原样考虑。示例 – 单元格 B10,其独立值为 2,并且在单元格 B9 中其上方紧接着另一个 L2,它是其上方 L1 的总和

问题是有时数据不正确,L2 可能不是它上面所有 L1 的总和(例如数据库可能遗漏了 L1 行)。我需要在 C 列中验证是否发生了此类错误。

所以如果没有错误,我在 C 列中的输出值应该与 L2、L3、L4、L5 的 B 列相同。或者不同的值,如果有错误。

范围是动态的,有数百行。

任何宏或预先存在的 excel 公式都可以做到这一点?

如果我能为这个问题提供任何帮助/代码或指示,我将不胜感激。

以下是我创建的部分代码。评论部分需要您的帮助。感谢您的帮助。

Sub Ttals()
lastrow = Worksheets("EMEA").Cells(Rows.Count, "AB").End(xlUp).Row
Debug.Print lastrow
For i = 2 To lastrow
If Cells(i, 1) = "L1" Then
    Cells(i, 3) = Cells(i, 2) 'This is pasting L1 values from column B/2 to column C/3

ElseIf Cells(i, 1) = "L2" Then
'Insert a function to search rows above this cell for values:
'If immediately above - L2/L3/L4/L5/L6 are encountered, paste value from column B/2 for this row
'If immediately above L1 is encountered, keep going above till more L1 are encoutered,
'and when any other L are encountered, stop going up and take a sum of all L1 in this range and post the sum

ElseIf Cells(i, 1) = "L3" Then
'Insert similar function which I can modify myself once I get the above function for L2

End If
Next
End Sub

您可以使用以下公式:

{=IF(VALUE(RIGHT(A1,1))>1,IF(COUNTIFS(INDIRECT("A1:A"&ROW()),A1)=1,SUMIFS(INDIRECT("B1:B"&ROW()),INDIRECT("A1:A"&ROW()),"L"&VALUE(RIGHT(A1,1))-1),SUMIFS(INDIRECT("B"&LARGE(IF($A:INDIRECT("A"&ROW())=A1,ROW($A:INDIRECT("A"&ROW()))-MIN(ROW($A:INDIRECT("A"&ROW())))+1),2)&":B"&ROW()),INDIRECT("A"&LARGE(IF($A:INDIRECT("A"&ROW())=A1,ROW($A:INDIRECT("A"&ROW()))-MIN(ROW($A:INDIRECT("A"&ROW())))+1),2)&":A"&ROW()),"L"&VALUE(RIGHT(A1,1))-1)),B1)}

尝试了不同的方法来检查上面行的值,但数组公式让我变得更好,所以下面是对 0 的检查:

{=IF(IF(VALUE(RIGHT(A1,1))>1,IF(COUNTIFS(INDIRECT("A1:A"&ROW()),A1)=1,SUMIFS(INDIRECT("B1:B"&ROW()),INDIRECT("A1:A"&ROW()),"L"&VALUE(RIGHT(A1,1))-1),SUMIFS(INDIRECT("B"&LARGE(IF($A:INDIRECT("A"&ROW())=A1,ROW($A:INDIRECT("A"&ROW()))-MIN(ROW($A:INDIRECT("A"&ROW())))+1),2)&":B"&ROW()),INDIRECT("A"&LARGE(IF($A:INDIRECT("A"&ROW())=A1,ROW($A:INDIRECT("A"&ROW()))-MIN(ROW($A:INDIRECT("A"&ROW())))+1),2)&":A"&ROW()),"L"&VALUE(RIGHT(A1,1))-1)),B1)=0,B1,IF(VALUE(RIGHT(A1,1))>1,IF(COUNTIFS(INDIRECT("A1:A"&ROW()),A1)=1,SUMIFS(INDIRECT("B1:B"&ROW()),INDIRECT("A1:A"&ROW()),"L"&VALUE(RIGHT(A1,1))-1),SUMIFS(INDIRECT("B"&LARGE(IF($A:INDIRECT("A"&ROW())=A1,ROW($A:INDIRECT("A"&ROW()))-MIN(ROW($A:INDIRECT("A"&ROW())))+1),2)&":B"&ROW()),INDIRECT("A"&LARGE(IF($A:INDIRECT("A"&ROW())=A1,ROW($A:INDIRECT("A"&ROW()))-MIN(ROW($A:INDIRECT("A"&ROW())))+1),2)&":A"&ROW()),"L"&VALUE(RIGHT(A1,1))-1)),B1)}

注意这是一个数组公式!粘贴在 cel C1 中并向下拖动。

这篇文章很长 :P