Custom Aggregate Function in MS Access

OK, I know aggregate functions MIN(...), AVG(...), SUM(...).
How can I write PROD(...) function that is similar to SUM?

         x1 + x2 + ... + xN
but computes product
         x1 * x2 *... xN

SELECT sum(salary), prod(rate) from whateverTable group by depID
Who is Participating?
Patrick MatthewsConnect With a Mentor Commented:
Hello midfde,

The UDF below, when placed in a regular VBA module, seems to be working.  Since the behavior is similar
to the "domain aggregate" functions, I named it DProd.

Some caveats:

1) If any of the factors that are being multiplied are Null, then the result will be Null.  If you want a zero
in this instance, just wrap the expression in Nz.

2) As with regular multiplication, if any of the factors are zero, the result will be zero

3) The function seems to be doing an implicit conversion to Double.  I tested it by passing a Long field
with vaues that would produce:
1 * 2 * 3 * ... * 100
which would, of course, exceed the ~2.1 billion limit for Long.  The answer I got back was ~9.3 x 10^157.
If you are passing the result to a variable or a column of type Integer or Long, just be aware that you
could get an overflow error if the factors are too big

You would use it like this:

SELECT depID, Sum(salary) AS TotSalary, DProd("[rate]", "[SomeTable]", "[depID] = " & [depID]) AS ProdRate
FROM SomeTable

If depID is not numeric...

SELECT depID, Sum(salary) AS TotSalary, DProd("[rate]", "[SomeTable]", "[depID] = '" & [depID] & "'") AS ProdRate
FROM SomeTable


Function DProd(FieldName As String, TableName As String, Optional Criteria As String = "")
    Dim SQL As String
    Dim rs As DAO.Recordset
    FieldName = "[" & Replace(Replace(FieldName, "[", ""), "]", "") & "]"
    TableName = "[" & Replace(Replace(TableName, "[", ""), "]", "") & "]"
    SQL = "SELECT " & FieldName & " FROM " & TableName
    If Criteria <> "" Then SQL = SQL & " WHERE " & Criteria
    Set rs = CurrentDb.OpenRecordset(SQL)
    If rs.EOF Then
        Prod = Null
        Prod = 1
        Do While Not rs.EOF
            Prod = Prod * rs.Fields(0)
    End If
    Set rs = Nothing
End Function

Open in new window

Kevin CrossChief Technology OfficerCommented:
Take a look at this:

The gist is to create your function to take in deptID for example, so usage like this:
SELECT sum(salary), prod(depID) from whateverTable group by depID

Or to make it more flexible, pass in tablename, columnname and where filters or just pass sql string itself.

Code sample below.  You would just keep multiplying by each rate you find in loop and then return.

Dim strSQL  As String
Dim db      As DAO.Database
Dim rs      As DAO.Recordset
  Set db = CurrentDb()
  strSQL = "SELECT ..." 
  Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
  Do While Not rs.EOF
    'do your thing
  set rs = nothing
  set db = nothing

Open in new window

midfdeAuthor Commented:
Thanks. I wonder what about custom aggregate functions in SQL Server environment
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.