【问题标题】:Excel VBA - if loop with dynamic filter rangeExcel VBA - 具有动态过滤范围的 if 循环
【发布时间】:2019-03-29 20:28:45
【问题描述】:

我有下表:

Filter   Notional  Type   Total
A          5000    A      _____
B          1000    A
           2500    B
           3600    C
           7500    C
           8000    B
           4500    C
           700     C

下面的代码是为了计算名义值的过滤总和:

    Sub filtersum()

    Dim filterA, filterB as Variant
        filterA = Cells (2, 1)
        filterB = Cells (3, 1)

    Dim i, n as Integer
        k = Cells.Find("Type").Offset(1, 0).Row
        n = Cells.Find("Type").End(xlDown).Row

    Dim sum as Double
        sum = 0

    For i = k To n
    If Cells(i, 3) = filterA Or Cells(i, 3) = filterB Then
        j = Cells(i, 3)
           sum = j + sum 
        End If
    Next i 

    Cells.(2, 4).Value = sum    'Result under "Total"

    End Sub

所以我现在正在做的是计算所有名义值的总和,即类型“A”或“B”。但是对于最终的应用程序,这还不够,因为现在我在代码中定义了每一个过滤条件(fiterA、filterB)。用户应该能够在表格中添加过滤条件,例如:

Filter   Notional  Type   Total
A          5000    A      _____
B          1000    A
C          2500    B
           3600    C
           7500    C
           8000    B
           4500    C
           700     C

现在我必须准备代码并为 if 条件添加另一个条件,这在最终应用程序中是不可取的。

希望你有什么想法可以解决我的问题,谢谢!

【问题讨论】:

  • 我会使用 SUMIFS 函数

标签: excel vba for-loop if-statement


【解决方案1】:

因此,我没有对 IF 语句中的每个过滤器单元进行“硬编码”,而是遍历过滤器列。

对于每个g(“过滤器”范围内的过滤器值),如果在“类型”列(C 列)中找到条件,它将检查每一行。如果找到匹配,它将求和。当一个过滤条件完成时(g),它将转到“过滤”列中的下一行。

Sub filtersum()

Dim filterA As Variant, filterB As Variant
    filterA = Cells(2, 1)
    filterB = Cells(3, 1)

Dim k As Long, n As Long, h As Long
    k = Cells.Find("Type").Offset(1, 0).Row
    n = Cells.Find("Type").End(xlDown).Row
    h = Cells.Find("Filter").End(xlDown).Row 'last row for column A, searching for "Filter"

Dim sum As Double
    sum = 0 'Sum variable


Dim g As Long, i As Long, j As Long
Dim filterCriteria As Variant 'Define your criteria it should look up


For g = k To h 'Look up for Filter column, from the same start cell as "Type" column to the same end cell as "Type". Then loop through all criterias.
    filterCriteria = Cells(g, 1).Value 'Get current criteria value
    For i = k To n 'Loop through column Type
        If Cells(i, 3) = filterCriteria Then 'If Type = filter criteria, then sum.
            j = Cells(i, 2) 'I think you have an typo in your example here, since sum should be done on column B, not column C.
            sum = j + sum 'Sum the values.
        End If
    Next i 'take next value in column C, "Type" column
Next g 'take next value in column A, "Filter" column
Cells(2, 4).Value = sum    'Result under "Total"
End Sub

【讨论】:

  • 非常感谢,这正是我正在寻找的解决方案!
  • 我很乐意为您提供帮助。你做了大部分工作。我只是再循环一次;)
【解决方案2】:

我会使用 sumifs。然后我会根据需要将公式向下扩展。这是单元格 D2 的公式

【讨论】:

  • 感谢您的快速响应,但此解决方案对我来说不是很有帮助。我需要一个动态条件范围,所以如果用户添加了过滤条件,我不想准备我的 vba 代码。
  • 为什么不能在单元格“E2”中添加 D 列的总和?那么你得到了你的总数,你可以在 A 列中指定额外的过滤器。(确保 D 列中的公式被复制到尽可能多的行中
  • 这只是一个示例表,在我的应用程序中,我不可能在中间执行此步骤
【解决方案3】:

您可以使用AutoFilter() 方法,将xlFilterValues 作为其Operator 参数值和WorksheetFunction.Subtotal() 函数对过滤后的单元格进行求和,如下所示

Option Explicit

Sub filtersum()

    Dim filters As Variant
    filters = Application.Transpose(Range("A2", Cells(Rows.Count, 1).End(xlUp)).Value)

    With Range("B1", Cells(Rows.Count, 3).End(xlUp))
        .AutoFilter Field:=2, Criteria1:=filters, Operator:=xlFilterValues
        Range("D2").Value = Application.WorksheetFunction.Subtotal(9, .Columns(1))
    End With
    ActiveSheet.AutoFilterMode = False

End Sub

【讨论】:

    猜你喜欢
    • 2018-05-07
    • 1970-01-01
    • 1970-01-01
    • 2020-11-15
    • 2015-08-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多