用于复杂过滤的excel vba代码

时间:2013-12-30 18:16:47

标签: excel excel-vba vba

我有以下数据集:

Name   Code   Output  Type

Alice  Apple   -100    B
Alice  Apple   +60     S
Alice  Banana   -52    S
Alice  Apple    +40    S
Alice  mango   -5000   S
Bob    Kiwi    -500    B
Bob    Kiwi    +500    S
Bob    peach   -40     S
Dan    Banana   -50    S
Dan     peach  +28     S

我想使用以下标准减少此数据:

  1. 具有给定名称的IF记录在“类型”列中的任何记录中都不包含“B”,那么我不想考虑它。所以“丹”记录已经出局。在5个Alice记录中,第一个记录中有“Type”“B”,Bob也有“Type”“B”。

  2. 对于其他人,我想知道哪些水果数字不会为零。

  3. 所以我希望看到这一点:

    Name   Code   output  Type
    Alice  Banana -52      S
    Alice  mango  -5000    S
    Bob    peach     -40   S 
    

    现在,首先我正在对名称和代码进行SumIfs。

       =SUMIFS($C$2:$C$21,$B$2:$B$21,B2,$A$2:$A$21,A2)
    

    然后我创建一个列,其中当type = B时我给出值1,否则为0。

     =IF(D2="B",1,0)
    

    然后我正在做一个Sumif,以确定哪些名称有“B”

     =SUMIF($A$2:$A$21,A2,$F$2:$F$21)
    

    然后我将过滤那些没有B且SUMIFS不为零的那些。

    现在这是单页内容。我打算在VBA宏中使用这些公式。有一个更好的方法吗?说不用创建新列?

1 个答案:

答案 0 :(得分:1)

假设您的列的顺序与上述顺序相同。以下代码将生成一个新的第5列,其中包含0,1。

Option Explicit
Option Compare Text

Sub SetFilter()
    Dim sh As Worksheet: Set sh = Sheet1
    ' YOU MUST add reference "Microsoft Scripting Runtime" from tools menu to use this object...
    Dim FruitSums As New Scripting.Dictionary ' key = name of fruit, value is running total
    FruitSums.CompareMode = TextCompare
    Dim iR As Integer
    Dim lbl As String
    Dim value As Variant
    'get fruit sums
    For iR = 2 To sh.UsedRange.Rows.Count
        lbl = sh.Cells(iR, 2)
        value = sh.Cells(iR, 3)
        If IsNumeric(value) Then
            If FruitSums.Exists(lbl) Then
                FruitSums(lbl) = FruitSums(lbl) + CLng(value)
            Else
                FruitSums(lbl) = CLng(value)
            End If
        End If
    Next
    ' calculate the filter column
    For iR = 2 To sh.UsedRange.Rows.Count
        If sh.Cells(iR, 4) = "B" Then
            sh.Cells(iR, 5) = 1 ' ok, is a B
        Else
            lbl = sh.Cells(iR, 2)
            If FruitSums.Exists(lbl) Then
                If CLng(FruitSums(lbl)) = 0 Then
                    sh.Cells(iR, 5) = 0 ' not ok, is total 0
                Else
                    sh.Cells(iR, 5) = 1 ' ok, is not 0
                End If
            Else ' this case should not occur
                sh.Cells(iR, 5) = -1 ' unexpected output.
            End If
        End If
    Next

End Sub