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