SUMIFS的VBA代码?

SUMIFS的VBA代码?,vba,excel,excel-2007,Vba,Excel,Excel 2007,我正在尝试编写一个自定义函数,该函数允许我从满足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可以大

我正在尝试编写一个自定义函数,该函数允许我从满足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可以大致做到这一点。但就我而言,这些假设是行不通的。

一个使用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")
一个使用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")

IMHO 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

函数MFind(范围为范围,参数数组Tests()为变量)为变量
'
“参数包括:
'要搜索的范围
'要在连续列中搜索的值
'除上次使用外的所有搜索值=
'最后一个搜索值使用>=
'函数返回范围中最后一列的值
'
Dim-vArr作为变体
Dim j尽可能长
暗k一样长
将图形变长
我们发现它是布尔型的

W X Y Z    AA
a b 6 ab6  1
a b 7 ab7  2
b b 7 bb7  3
vArr=theRange.Value2
nParams=UBound(测试)-LBound(测试)+1
如果nParams>=UBound(vArr,2),则
MFind=CVErr(XLERR值)
退出功能
如果结束
对于j=1至UBound(vArr)
blFound=True
对于k=LBound(测试)至NPAAMS-2
如果vArr(j,k+1)测试(k),那么
blFound=False
退出
如果结束
下一个k
如果找到的话
如果vArr(j,nParams)>=测试(nParams-1),则
MFind=vArr(j,UBound(vArr,2))
退出
如果结束
如果结束
下一个j
端函数

IMHO 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

函数MFind(范围为范围,参数数组Tests()为变量)为变量
'
“参数包括:
'要搜索的范围
'要在连续列中搜索的值
'除上次使用外的所有搜索值=
'最后一个搜索值使用>=
'函数返回范围中最后一列的值
'
Dim-vArr作为变体
Dim j尽可能长
暗k一样长
将图形变长
我们发现它是布尔型的

W X Y Z    AA
a b 6 ab6  1
a b 7 ab7  2
b b 7 bb7  3
vArr=theRange.Value2
nParams=UBound(测试)-LBound(测试)+1
如果nParams>=UBound(vArr,2),则
MFind=CVErr(XLERR值)
退出功能
如果结束
对于j=1至UBound(vArr)
blFound=True
对于k=LBound(测试)至NPAAMS-2
如果vArr(j,k+1)测试(k),那么
blFound=False
退出
如果结束
下一个k
如果找到的话
如果vArr(j,nParams)>=测试(nParams-1),则
MFind=vArr(j,UBound(vArr,2))
退出
如果结束
如果结束
下一个j
端函数

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

VLOOKUP()
仅通过查找一个“键”起作用,但您可以在左侧的帮助器列中创建串联键。例如:


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

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

VLOOKUP()
仅通过查找一个“键”起作用,但您可以在左侧的帮助器列中创建串联键。例如:


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

而不是写入另一个工作表。函数是否可以返回标量值以便在公式中使用?我应该能够用命名表范围替换[Sheet1$],正确吗?是的,例如,选择。。。从表1感谢所有帮助。最后一个问题:您知道SUMIFS函数是否像这样利用oledb吗?还是使用了更高效的机制?SumIf是一个内置函数,使用Microsoft用来编写Excel的任何东西:)。您可以在VBA中使用内置函数,当然有很多方法可以满足您的需要,但我发现当存在多个条件和一组记录时,ADO非常有用。函数是否可以返回标量值以便在公式中使用?我应该能够替换[Sheet1$]命名表范围是否正确?是,例如,选择。。。从表1感谢所有帮助。最后一个问题:您知道SUMIFS函数是否像这样利用oledb吗?还是使用了更高效的机制?SumIf是一个内置函数,使用Microsoft用来编写Excel的任何东西:)。您可以在VBA中使用内置函数,毫无疑问,有许多方法可以实现您想要的功能,但我发现,当存在多个条件和一组记录时,ADO非常有用。