Question

I'm trying to write a custom function that will let me retrieve a cell from the first row in a range that meets x number of criteria. I imagine this would be very similar to the way SUMIFS works, just simpler in that it doesn't continue processing after the first match.

Does anyone know code to reproduce the SUMIFS (excel 07) function in VBA?

So, for example, if I have a table in excel like:

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

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).

SUMIFS can approximately do this, assuming the record I want is unique and I'm looking to return a number. For my purposes though, those assumptions won't work.

Was it helpful?

Solution

IMHO ADO is not suitable for use in excel worksheet functions (poor performance and cannot easily be used on the worksheet containing the data). here is a VBA alternative:


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

OTHER TIPS

An example using 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")

Deeno, having a UDF for this is very useful but you could also use plain old =VLOOKUP().

VLOOKUP() only works by looking up one "key" but you can make a concatenated key in a helper column to the left. eg:

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

Then =VLOOKUP(A1,$Z$1:$AA$3,2,FALSE) if A1 had the value you are looking for. If your data is more complicated you could join the data with an unused character (eg: a pipe) so you have a|B|6 instead of ab6.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top