【问题标题】:Excel: Calculate difference between cell and cell above in an auto filtered tableExcel:计算自动过滤表中单元格和单元格之间的差异
【发布时间】:2019-01-22 03:24:28
【问题描述】:

我有一个表,其中 A 列包含递增的数值,B 列是一堆名称。我需要根据名称过滤表格,并使用当前行中 A 列中的值与上面的单元格之间的差异更新 C 列..

For example, I'd like to have something like this 哪一个, when filtered according to the Name column, should update the difference like so

我曾尝试以几种不同的方式使用 SUBTOTAL 函数,但均无济于事。理想情况下,一旦更改表中的过滤器,它就会更新。我尝试在 VBA 中执行此操作,但到目前为止,我已经获得了仅使用硬编码过滤条件进行过滤的宏。

欢迎并非常感谢 excel 公式/python/vba 中的解决方案!

如果这个问题不符合标准,我提前道歉,因为我是新来的 :) 提前谢谢!

@JvdV:This 是我试图实现你的公式的结果,This 是经过过滤的。

【问题讨论】:

  • 看看你的截图,我相信你在范围上犯了一个错误:)。请仔细看!如果您找不到错误,请告诉我您的单元格 C2 中当前有什么公式。

标签: excel vba filter subtotal


【解决方案1】:

修订答案

因此,在您的解释之后,我研究了一个公式,该公式将为您提供当前行 B 值减去之前 A 值出现的 B 值的差值。

=IFERROR(B2-LOOKUP(2,1/($A$1:A1=A2),$B$1:B2),0)

获取您的样本数据,它看起来像这样:

然后当你应用过滤器时,它会是这样的:

因此,通过这种解决方法,您在未应用过滤器时没有正确的值,但在这种情况下,我假设您对过滤时的差异感兴趣!

在单元格C2中输入公式并向下拖动。

编辑

如果这不是您想要的答案,并且您确实在未过滤时需要这些值,请使用如下 UDF:

Public Function LastVisibleCell(CL As Range) As Long

Dim RW As Long, X As Long
RW = CL.Row - 1
On Error GoTo 1

If RW > 1 Then
    For X = RW To 1 Step -1
        If ActiveSheet.Rows(X).EntireRow.Hidden Then
        Else
            LastVisibleCell = Cells(CL.Row, 2).Value - Cells(X, 2).Value
            Exit For
        End If
    Next X
Else
1:    LastVisibleCell = 0
End If

End Function

从单元格C2 调用它,例如:=LastVisibleCell(A2) 并向下拖动。当您应用过滤器时,单元格将更新。

请注意,在大型数据集上更新需要很长时间!

【讨论】:

  • 您好 JvdV,感谢您的回复!不幸的是,这不是我想要的。再次,为含糊而道歉,为了清楚起见,我已经更新了问题!
  • 嗨@JvdV,谢谢!这很好用!我将数据类型更改为双精度以允许小数点。再次感谢您!
【解决方案2】:

经过 3 天的激烈(尽管无效)谷歌搜索,我终于在堆栈溢出时遇到了这个 answer

但是,由于我正在处理大量数据(>150,000 行),因此问题中的方法使用了太多内存。仅使用 VBA 将公式粘贴到可见单元格中似乎并不能缓解问题。

Sub CopyPasteFormula()
    Dim Ws As Worksheet
    Dim LRow As Long
    Dim PasteRng As Range

    Set Ws = Worksheets("Translated Data")
    Ws.Range("$D$2:$D$200000").AutoFilter Field:=4, Criteria1:="<>-", Operator:=xlFilterValues
    LRow = Ws.Range("D" & Rows.Count).End(xlUp).Row
    Set PasteRng = Ws.Range("A3:A" & LRow).SpecialCells(xlCellTypeVisible)
    Ws.Range("A3").Copy
    PasteRng.PasteSpecial xlPasteFormulas
    Application.CutCopyMode = False
End Sub

以上是我尝试减少内存使用的宏代码...感谢任何反馈!

【讨论】:

  • 如果您感兴趣的只是在过滤后获得两行之间的差异,您可以应用如下公式:=IFERROR(B3-LOOKUP(2,1/($A$2:A2=A3),$B$2:B2),"")。如果第一行是标题,则进入单元格B3。往下拖就行了。当没有应用过滤器时,这没有多大意义。
  • 如果您想留在 VBA 代码中,可以考虑在 .FindNext 循环中使用过滤器值粘贴您的公式。此外,您可以通过 vba 提取最后一个可见单元格的值来获得所需的值,而不是粘贴公式。代码应该不难组合。
  • 嗨@JvdV,您的公式似乎对我不起作用.. 理想情况下,我会远离 VBA,而更多地使用公式。不管怎么说,还是要谢谢你!将继续搜索
  • 该公式适用于以下假设:1) 名称在 A 列中。2) 数字在 B 列中。3)。第 1 行中的标题。 4)公式粘贴在 C3 中(不是 B3,我的错),需要向下拖动。如果它不起作用,请给我看你所做的截图。
  • @JvdV,我在问题中附上了屏幕截图。现在我也在根据我在网上找到的一些代码(无法再找到链接)研究解决方法:Public Function NextVisibleCell(Range As Range) As Range Application.Volatile Dim i As Long Set Range = Range.Cells(Range.Rows.Count, Range.Columns.Count) For i = 1 To Rows.Count - Range.Row If Not Range.Offset(i).EntireRow.Hidden Then Set NextVisibleCell = Range.Offset(i) Exit Function End If Next i End Function 但我无法让它引用上一行,只有当前...
猜你喜欢
  • 2016-03-17
  • 2017-02-26
  • 1970-01-01
  • 1970-01-01
  • 2013-03-09
  • 2017-07-09
  • 1970-01-01
  • 2017-09-04
  • 1970-01-01
相关资源
最近更新 更多