Concatenate field and remove duplicates (1 Viewer)

jetersauce

Registered User.
Local time
Today, 10:19
Joined
Dec 21, 2010
Messages
20
I have a report that needs to take all of the values from a field concatenate them into a line and remove the duplicates. I have tried some VBA concat modules but haven't been successful in finding a solution.

I need this:
OrderID
1030
1031
1049
1053
1053
1054
1054
1054
1059
1059
1060
1060

To show on the report as:
Order IDs: 1030, 1031, 1049, 1053, 1054, 1059, 1060

Any ideas on how to do this?
(I originally posted this in the Reports forum but I think the VBA forum is more appropriate)
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
I have tried some VBA concat modules...

In the modules you have tried, were you able to get the values concatenated but with the duplicates? If so, a slight modification may solve the problem.

Allen Browne has a function on his site that will concatenated the values. In that code is a query that, with modifications, will get rid of the duplicates. This is the section of code to which I am referring:

Code:
strSql = "SELECT " & strField & " FROM " & strTable

To just get unique values (i.e. no duplicates), you would only need to add the keyword DISTINCT to the query

Code:
strSql = "SELECT [COLOR="Red"]DISTINCT[/COLOR] " & strField & " FROM " & strTable
 

jetersauce

Registered User.
Local time
Today, 10:19
Joined
Dec 21, 2010
Messages
20
Yes this is one of the ones I tried, but I could not get it to work. In the query I put

=ConcatRelated("OrderID", "Orders", )

But I keep getting the error
"Undefined function 'ConcatRelated' in expression."

The code I pasted into my module is
Code:
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:
    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

What am I doing wrong?
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
How are the orderID's related to one another? Are they all for a particular customer? If so then you need to supply the customerID to the function.

Can you please post the query in which you tried to use the function?
Can you please post the table structure of the Orders table?

Out of curiosity, you have an extra comma in the function after "Orders" was that intentional or a typo?

ConcatRelated("OrderID", "Orders", )
 

jetersauce

Registered User.
Local time
Today, 10:19
Joined
Dec 21, 2010
Messages
20
The comma was a typo. It looks like I got that error because I named the module with the same name as the function ("ConcatRelated") :eek:

Changing the query in the function to SELECT DISTINCT eliminated all the duplicates :D Thanks for the help!
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
You're welcome. Glad to hear that you got it working!
 

bardok2000

New member
Local time
Today, 10:19
Joined
Jul 17, 2012
Messages
3
Hi

Sorry I'm new on this, I use the same function, and I use the "SELECT DISTINCT " but instead of deliting the reow that is duplicated it add the infromation, for example

colum a colum b
a 1
b 2
a 2

the result shold be

column a column b

a 1, 2
b 2

but it show

column a column b
a 1, 2
a 1, 2
b 2

Any idea?
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
You can use either of 2 approaches.

First Approach:

Create a query that just selects the distinct values in columnA

query name:qryInitialQuery

SELECT DISTINCT tblData.ColumnA
FROM tblData;


Then create another query that uses the above query & calls the function (the following assumes that columnA is a text field and thus must be delimited by single quotes in the function call)

SELECT qryInitialQuery.ColumnA, ConcatRelated("columnB","tblData","columnA='" & qryInitialQuery.ColumnA & "'") AS ConcatenatedData
FROM qryInitialQuery;


Second Approach:

Call the function from within an aggregate query:

SELECT tblData.ColumnA, concatrelated("columnB","tblData","columnA='" & [columnA] & "'") AS ConcatenatedData
FROM tblData
GROUP BY tblData.ColumnA, concatrelated("columnB","tblData","columnA='" & [columnA] & "'");
 

bardok2000

New member
Local time
Today, 10:19
Joined
Jul 17, 2012
Messages
3
sorry I think I should be more specific,, the function that I'm using Im using it from 3 diferent fields, here is the example of the function and some of the information that I'm trying to concatenated

Order# product# Carrier Tracking number
123 a B 123
123 b B 456
567 a A 123
123 a B 567

And the resould should be checking the first 3, Order, product and carrier and concatenated the tracking only if it is iqual on the 3 fields so in this case will only concatecated order 123 with te product a with the carrier B

so I'm not sure if the 2 options will work :S
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
You just need to specify the 3 criteria in the WHERE portion of the Function. A query similar to this should work. You will have to adjust the delimiters based on the datatypes of the 3 fields

SELECT tblOrders.OrderNo, tblOrders.ProductNo, tblOrders.Carrier, concatrelated("TrackingNumber", "tblOrders","OrderNo=" & tblOrders.OrderNo & " AND ProductNo='" & tblOrders.ProductNo & "' AND carrier='" & tblOrders.Carrier & "'") as ConcatenatedTrackingNumbers
FROM tblOrders
GROUP BY tblOrders.OrderNo, tblOrders.ProductNo, tblOrders.Carrier;


The output to the above query would look like this:

OrderNo|ProductNo|Carrier|ConcatenatedTrackingNumbers
123|a|B|123, 567
123|b|B|456
567|a|A|123
 

noppojp

New member
Local time
Tomorrow, 00:19
Joined
Apr 27, 2011
Messages
2
i'm using the same VBA code in this thread to accomplish something very similar, but i get dupes. Can i ask questions here, or must i start a new thread? Seems a waste to start a new thread.
:confused:
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
Technically you do not have to create a new thread, but others may only be monitoring new threads, so you may get more people helping with a new thread.

I am traveling at present so I will not be on-line much over the next few days, but I'll try to help when I can.
 

PIPTULIP

New member
Local time
Today, 08:19
Joined
Jul 15, 2016
Messages
1
Ok hopefully someone can help with this one:
I used the concatRelated coding and created a Module, works great. However I need to have it not list duplicates. Some basic info:

Table Name: tblEventDetails
Columns: Trip ID, Location
-----Use ConcatRelated in a query.

I track travel (1 trip, multiple events with possible different locations) for a unit and need to run reports with the "Location" field together. However if it happens they may stay in the same city.

I tried to add "DISTICT" to the correct string in the Module, but I get a random error, for module that has nothing to do with the query or the ConcatRelated Module.

Samples:
tblEventDetails
Trip ID Location
1 London, UK
1 London, UK
1 London, UK
2 Boston, MA
2 New York, NY
3 New York, NY
3 Paris, FR
3 London, UK

What I need in a query

Trip ID Location(s)
1 London, UK
2 Boston, MA/ New York, NY
3 New York, NY/ Paris, FR/ London, UK

Thanks
 

jzwp22

Access Hobbyist
Local time
Today, 11:19
Joined
Mar 15, 2008
Messages
2,629
In your query you will have to add the ConcatRelated() function with criteria based on the TripID

SELECT tblEventDetails.tripID, ConcateRelated("Locations","tblEventDetails","TripID=" & tblEventDetails.TripID) as ConcatenatedLocations
FROM tblEventDetails
GROUP BY tblEventDetails.tripID

By the way, if your field name Trip ID does have a space in it, I would recommend removing the space or you will always have to enclose it in square brackets [] in every query you create.
 

Users who are viewing this thread

Top Bottom