views:

796

answers:

4

Ok so a guy at work has a little access database he uses to keep track of things. He has this form that he uses that already queries what he needs and produces the results on a form and that is really all he needs.

One thing is that he has duplicates for every record that comes up with a different "Type" as a field "indentifier" (what I call it)...here is an example:

ID     Name          Price     Type
1      Prodcut A     $10       A1
1      Product A     $10       A2
1      Product A     $10       A3
2      Product B     $12       A1
etc

naturally this is supposed to occur and he wants to see all the types but given it end up being a mile long, he asked me if there was a way to concatenate the "types" so th following would be displayed:

ID     Name          Price     Type
1      Prodcut A     $10       A1, A2, A3
1      Product B     $12       A1, A2, A3
1      Product C     $14       A1, A2, A3
2      Product D     $7        A1, A2, A3

...on the form. Can anyone please help me with this? Thanks!

+1  A: 

Something on these lines may suit, but concatenating is usually not a good idea:

   Function ConcatList(strSQL As String, strDelim, _
                       ParamArray NameList() As Variant)
   ''Reference: Microsoft DAO x.x Object Library
   Dim db As Database
   Dim rs As DAO.Recordset
   Dim strList As String

   Set db = CurrentDb

   If strSQL <> "" Then
       Set rs = db.OpenRecordset(strSQL)

       Do While Not rs.EOF
           strList = strList & strDelim & rs.Fields(0)
           rs.MoveNext
       Loop

       strList = Mid(strList, Len(strDelim) + 1)
   Else

       strList = Join(NameList, strDelim)
   End If

   ConcatList = strList

   End Function

FROM: http://wiki.lessthandot.com/index.php/Concatenate%5Fa%5FList%5Finto%5Fa%5FSingle%5FField%5F%28Column)

Remou
yeah i understand, but for what this guy needs it for it actually makes sense because he's needs are not great, and for every Code# and Descrip of that event code, he needs to see every "instance type" for which that may apply....and that is basically it.I know concatenation is like relational back tracking, but...??
Justin
thanks for the help as always Remou!
Justin
I guess you can't always win :) . You are most welcome.
Remou
+2  A: 

I found an example (here) that seems to be exactly what you are looking for:
Concatenate Column Values from Multiple Rows into a Single Column with Access

From the above link:

The Problem

Coming up with a meaningful title for this article was the hardest part. The issue is one that I have seen a couple times in the Access newsgroups, but it is hard to describe without a specific example. One post to comp.databases.ms-access some years ago put it this way:

I would like to combine a field's values from multiple records in a single field. For example:

Last     First     Code
-------  --------- ----
Lesand   Danny       1
Lesand   Danny       2
Lesand   Danny       3
Benedi   Eric        7
Benedi   Eric       14

Result should look like:

Last     First     Codes
-------  --------- -----
Lesand   Danny     1,2,3
Benedi   Eric       7,14
Nick D
thanks....this is exactly what I was looking for
Justin
Thanks for the link
Philippe Grondier
+2  A: 

OK, i found a function created in the VBA, which can be used in the query to retrieve the data for the form.

function is

Public Function ConcatRelated(strField As String, _
    strTable As String, _
    Optional strWhere As String, _
    Optional strOrderBy As String, _
    Optional strSeparator = ", ") As Variant
On Error GoTo Err_Handler
    'Purpose:   Generate a concatenated string of related records.
    'Return:    String variant, or Null if no matches.
    'Arguments: strField = name of field to get results from and concatenate.
    '           strTable = name of a table or query.
    '           strWhere = WHERE clause to choose the right values.
    '           strOrderBy = ORDER BY clause, for sorting the values.
    '           strSeparator = characters to use between the concatenated values.
    'Notes:     1. Use square brackets around field/table names with spaces or odd characters.
    '           2. strField can be a Multi-valued field (A2007 and later), but strOrderBy cannot.
    '           3. Nulls are omitted, zero-length strings (ZLSs) are returned as ZLSs.
    '           4. Returning more than 255 characters to a recordset triggers this Access bug:
    '               http://allenbrowne.com/bug-16.html
    Dim rs As DAO.Recordset         'Related records
    Dim rsMV As DAO.Recordset       'Multi-valued field recordset
    Dim strSql As String            'SQL statement
    Dim strOut As String            'Output string to concatenate to.
    Dim lngLen As Long              'Length of string.
    Dim bIsMultiValue As Boolean    'Flag if strField is a multi-valued field.

    'Initialize to Null
    ConcatRelated = Null

    'Build SQL string, and get the records.
    strSql = "SELECT " & strField & " FROM " & strTable
    If strWhere <> vbNullString Then
        strSql = strSql & " WHERE " & strWhere
    End If
    If strOrderBy <> vbNullString Then
        strSql = strSql & " ORDER BY " & strOrderBy
    End If
    Set rs = DBEngine(0)(0).OpenRecordset(strSql, dbOpenDynaset)
    'Determine if the requested field is multi-valued (Type is above 100.)
    bIsMultiValue = (rs(0).Type > 100)

    'Loop through the matching records
    Do While Not rs.EOF
        If bIsMultiValue Then
            'For multi-valued field, loop through the values
            Set rsMV = rs(0).Value
            Do While Not rsMV.EOF
                If Not IsNull(rsMV(0)) Then
                    strOut = strOut & rsMV(0) & strSeparator
                End If
                rsMV.MoveNext
            Loop
            Set rsMV = Nothing
        ElseIf Not IsNull(rs(0)) Then
            strOut = strOut & rs(0) & strSeparator
        End If
        rs.MoveNext
    Loop
    rs.Close

    'Return the string without the trailing separator.
    lngLen = Len(strOut) - Len(strSeparator)
    If lngLen > 0 Then
        ConcatRelated = Left(strOut, lngLen)
    End If

Exit_Handler:
    'Clean up
    Set rsMV = Nothing
    Set rs = Nothing
    Exit Function

Err_Handler:
    MsgBox "Error " & Err.Number & ": " & Err.Description, vbExclamation, "ConcatRelated()"
    Resume Exit_Handler
End Function

and is used in the query as

SELECT Table1.ID, Table1.ProductName, Table1.ProductPrice, ConcatRelated("Type","Table1","ID = " & [Table1]![ID] & " AND ProductName = """ & [Table1]![ProductName] & """ AND ProductPrice = " & [Table1]![ProductPrice]) AS Expr1
FROM Table1
GROUP BY Table1.ID, Table1.ProductName, Table1.ProductPrice, ConcatRelated("Type","Table1","ID = " & [Table1]![ID] & " AND ProductName = """ & [Table1]![ProductName] & """ AND ProductPrice = " & [Table1]![ProductPrice]);
astander
sweet example. thanks very much!
Justin
A: 

Why don't you try the "crosstab query" solution?

Philippe Grondier
Crosstab creates a column for each value, not a delimited list of values in a single field. It's also going to produce a variable number of columns (unless you cleverly engineer your SQL to use your lookup table as the column heading source).
David-W-Fenton
I agree with your restrictions. This is a 'could be' solution, depending on the original situation.
Philippe Grondier