【问题标题】:VBA code for SUMIFS?SUMIFS 的 VBA 代码?
【发布时间】:2010-09-30 12:21:59
【问题描述】:

我正在尝试编写一个自定义函数,它可以让我从满足 x 个条件的范围内的第一行中检索一个单元格。我想这将与 SUMIFS 的工作方式非常相似,只是更简单,因为它不会在第一场比赛后继续处理。

有人知道在 VBA 中重现 SUMIFS (excel 07) 函数的代码吗?

因此,例如,如果我在 excel 中有一个表格,例如:

W X Y Z
a b 6 1
a b 7 2
b b 7 3

我希望能够编写一个函数,该函数将为我提供 Z 列中的值,其中列 W=a、X=b、Y>=7(即值 2)。

SUMIFS 可以大致做到这一点,假设我想要的记录是唯一的并且我希望返回一个数字。但就我的目的而言,这些假设是行不通的。

【问题讨论】:

    标签: vba excel excel-2007


    【解决方案1】:

    使用 ADO 的示例。

    strFile = Workbooks(1).FullName
    strCon = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & strFile _
        & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=1"";"
    
    Set cn = CreateObject("ADODB.Connection")
    Set rs = CreateObject("ADODB.Recordset")
    
    cn.Open strCon
    
    'I want to be able to write a function that will give me the value '
    'in column Z where columns W=a, X=b, Y>=7 '
    '(in other words the value 2).' 
    
    strSQL = "SELECT Top 1 Z " _
             & "FROM [Sheet1$] " _
             & "WHERE W='a' And X='b' And Y>=7"
    
    rs.Open strSQL, cn
    
    Result = rs.Fields("Z")
    

    【讨论】:

    • 函数是否可以返回一个标量值以便在公式中使用,而不是写入另一张表?
    • 我应该能够将 [Sheet1$] 替换为命名表范围正确吗?
    • 是的,例如,从 Table1 中选择 ...
    • 感谢 Remou 的所有帮助。最后一个问题:你知道 SUMIFS 函数是否像这样利用 oledb 吗?还是使用更高效的机制?
    • SumIf 是一个内置函数,使用 Microsoft 用来编写 Excel 的任何东西 :)。您可以在 VBA 中使用内置函数,毫无疑问,您可以通过多种方式来做您想做的事情,但我发现 ADO 在有多个条件和一组记录时非常有用。
    【解决方案2】:

    恕我直言,ADO 不适合在 excel 工作表函数中使用(性能差,不能轻易在包含数据的工作表上使用)。 这是一个 VBA 替代方案:

    
    Function MFind(theRange As Range, ParamArray Tests() As Variant) As Variant
    '
    ' Parameters are:
    ' The Range to be searched
    ' the values to be searched for in successive columns
    ' all search values except the last use =
    ' the last search value uses >=
    ' the function returns the value from the last column in the range
    '
        Dim vArr As Variant
        Dim j As Long
        Dim k As Long
        Dim nParams As Long
        Dim blFound As Boolean
    
    
    vArr = theRange.Value2
    nParams = UBound(Tests) - LBound(Tests) + 1
    If nParams >= UBound(vArr, 2) Then
        MFind = CVErr(xlErrValue)
        Exit Function
    End If
    
    For j = 1 To UBound(vArr)
        blFound = True
        For k = LBound(Tests) To nParams - 2
            If vArr(j, k + 1) <> Tests(k) Then
                blFound = False
                Exit For
            End If
        Next k
        If blFound Then
            If vArr(j, nParams) >= Tests(nParams - 1) Then
                MFind = vArr(j, UBound(vArr, 2))
                Exit For
            End If
        End If
    Next j
    

    End Function

    【讨论】:

      【解决方案3】:

      Deeno,为此使用 UDF 非常有用,但您也可以使用普通的旧 =VLOOKUP()

      VLOOKUP() 只能通过查找一个“键”来工作,但您可以在左侧的帮助列中创建一个连接键。例如:

      W X Y Z    AA
      a b 6 ab6  1
      a b 7 ab7  2
      b b 7 bb7  3
      

      然后=VLOOKUP(A1,$Z$1:$AA$3,2,FALSE) 如果 A1 具有您正在寻找的值。如果您的数据更复杂,您可以使用未使用的字符(例如:管道)连接数据,这样您就有 a|B|6 而不是 ab6。

      【讨论】:

        猜你喜欢
        • 2013-05-27
        • 2020-10-09
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多