简体   繁体   中英

Excel VBA - if loop with dynamic filter range

I have the following table:

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

And the following code in order to calculate the filtered sum of notional values:

    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

So what I am doing right now is calculating the sum of all notional values, that are Type "A" or "B". But for the final application this is not sufficient because now I am defining every single filter criteria in the code (fiterA, filterB). The user should be able to add filter criteria in the table like:

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

Right now I would have to prepare the code and add another criteria for the if condition, which is not desirable in the final application.

I hope you have any ideas to solve my problem, Thanks!

I would use sumifs. I would then extend the formula down as needed. That's the formula for cell D2 在此处输入图片说明

So instead of "hard coding" each filter cell in the IF statement, I loop through the filter column.

For each g (filter value in range "Filter"), it will check for every row if the criteria is found in column "Type" (Column C ). If match is found it will sum. When one filter criteria is done ( g ) it will go to next row in "Filter" column.

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

you can use AutoFilter() method with xlFilterValues as its Operator parameter value and WorksheetFunction.Subtotal() function to sum up filtered cells, as follows

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM