I have a query where one of the fields is a function I wrote to get the due dates for trainings.
The function works and when I run my query it gives the correct dates but when I try to put in a criteria in the query to for example only output the due dates that are <31 days it gives me the error:
Data type mismatch in criteria expression
This is in the field for the query:
Due Date: getDueDate([Workday_Excel_Update].[Course Number])
This is the function:
Function getDueDate(CourseNum As String)
Dim yearCounter As Integer
Dim yearStart As Date
Dim yearNow As Integer
Dim monthFreq As Integer
Dim daysDue As Integer
'check if course number is part of the tracked trainings
If Not IsNull(DLookup("CourseName", "CourseNumbers", "CourseNumber = '" & CourseNum & "'")) Then
'if it is part of tracked training calculate date
monthFreq = DLookup("[Months]", "CourseNumbers", "CourseNumber = '" & CourseNum & "'")
yearStart = DLookup("[Frequency]", "CourseNumbers", "CourseNumber = '" & CourseNum & "'")
yearCounter = Year(yearStart)
yearNow = Year(Date)
While yearCounter < yearNow
yearStart = DateAdd("m", monthFreq, yearStart)
yearCounter = yearCounter + (monthFreq / 12)
Wend
daysDue = CInt(DateDiff("d", Date, yearStart))
'Else
'daysDue = 0
End If
getDueDate = daysDue
End Function
Example data:
CourseNumbers (Table)
CourseNumber
CourseName
Frequency
Months
1234
1234-training
1900-12-31
12
Workday_Excel_Update (Linked Table)
User ID
Badge ID
First Name
Last Name
Email Address
Primary Supervisor
Completion Date
Course Title
Course Number
Lesson Completion Status
0022334455
54321
Frank
Smith
frank.smith#work.com
John Leblanc
2021-05-20 2:59:54 PM
11234-training
1234
Not Started
SQL code of the Query:
SELECT Workday_Excel_Update.[User ID], Workday_Excel_Update.[Badge ID], Workday_Excel_Update.[First Name], Workday_Excel_Update.[Last Name], Workday_Excel_Update.[Email Address], Workday_Excel_Update.[Primary Supervisor], Workday_Excel_Update.[Completion Date], (getDueDate([Workday_Excel_Update].[Course Number])) AS [Days Until Due Date], Workday_Excel_Update.[Course Title], Workday_Excel_Update.[Lesson Completion Status]
FROM CourseNumbers INNER JOIN Workday_Excel_Update ON CourseNumbers.CourseNumber = Workday_Excel_Update.[Course Number]
WHERE (((Workday_Excel_Update.[Lesson Completion Status])<>"Completed" Or (Workday_Excel_Update.[Lesson Completion Status]) Is Null))
ORDER BY (getDueDate([Workday_Excel_Update].[Course Number]));
The getDueDate() function in the query will take as input a course number from another table which has a registration date for each employee. The registration date goes through a DateDiff() with the calculated due date and outputs an integer indicating the number of days left until the training is due or the number of days past the due date.
Query criteria
I also get the following error when I try to filter the query
Related
I use vb.net 2012 and msaccess2016 as database. I Have 4 tables. Item master,closing,Purchase,Issue. Now I want to get the result for a period in below formatted datagridview. Below are columns.
Item Name(Item Master)
Category(Item Master)
Unit(Item Master)
Sum of Quantity(closing)
Sum of Quantity(Purchase)
Sum of Quantity(Issue)
I have create a query with Item master and Closing and it's working. But when I try to purchase or issue there is no data. Purchase and issue table got no data.
Dim sdate, edate As Date
sdate = dtsdate.Value
edate = dtedate.Value
Dim sqlSelect As String = "SELECT itemmaster.[Item Name], itemmaster.Category, itemmaster.Unit," _
& " Sum(Closing.Qty) AS Opening FROM itemmaster INNER JOIN Closing ON " _
& "itemmaster.[Item Name] = Closing.[Item Name] WHERE(((Closing.closeDate) >= #" & sdate & " # And (Closing.closeDate) <=#" & edate & " #))" _
& " GROUP BY itemmaster.[Item Name], itemmaster.Category, itemmaster.Unit"
Try
Dim con As New Odbc.OdbcConnection
con.ConnectionString = "Dsn=sdbinventory;"
Dim dt As New DataTable("user2")
Using cmd = New Odbc.OdbcCommand(sqlSelect, con)
con.Open()
Dim da As New System.Data.Odbc.OdbcDataAdapter(sqlSelect, con)
da.Fill(dt)
con.Close()
End Using
dgtvreport.DataSource = dt
Catch ex As Exception
Throw
End Try
Can you please help me to add rest two columns.
Thanks
My query
PARAMETERS sdate DateTime, edate DateTime;
SELECT itemmaster.[Item Name], itemmaster.Category, itemmaster.Unit, Sum(Closing.Qty) AS SumOfQty1, Sum(Purchase.Qty) AS SumOfQty, Sum(Issue.Quantity) AS SumOfQuantity
FROM ((itemmaster INNER JOIN Closing ON itemmaster.[Item Name] = Closing.[Item Name]) INNER JOIN Issue ON itemmaster.[Item Name] = Issue.[Item Name]) INNER JOIN Purchase ON itemmaster.[Item Name] = Purchase.[Item Name]
WHERE (((Closing.closeDate)>=[sdate] And (Closing.closeDate)<=[edate]) AND ((Purchase.PDate)>=[sdate] And (Purchase.PDate)<=[edate]) AND ((Issue.Idate)>=[sdate] And (Issue.Idate)<=[edate]))
GROUP BY itemmaster.[Item Name], itemmaster.Category, itemmaster.Unit;
I have tried to run it in access. Also have added sample data. I just want to import all item names,category and unit from itemmaster. Now I want to add opening stock in next column and purchase and issue. I want to create and itemwise report.
Like
Item Name Category Unit Opening Purchased Issued Balance
item1 Grocery Kg 2 3 4 1
item2 beverages PCS 0 1 1 0
Item3 vegetables kg 2 0 0 2
item4 consumable Pkt 10 2 1 11
#june7 yes I belive your is the best answer which is also know by me but I have searched if there is any other option and in this process you have really gave me the in depth knowledge and differences about the different type of queries. thanks.
I have data imported into a temporary table in MSAccess which looks like this:
to which I have added the "Gap" and "Previous/Current" columns that I need to calculate using an SQL Query. The "Gap Threshold" is User input or PARAMETER supplied to Query and for e.g. is 300. The GlobalID groups ItemID's whereas each ItemID is unique number.
What i want to do is calculate the GAP
(GAP = TEMPORARY_1![VERSION DATE] - TEMPORARY![VERSION DATE])
between ItemID's of similar GlobalID's and identify the items having GAP > GAP THRESHOLD value. Based on this GAP, for each GlobalID-grouped ItemID's, I want to determine which is the "Previous" ItemID and which is the "Current" ItemID.
i.e. determine which is Previous Item and which is Current Item, having a GAP of more than 300 days between them.
Finally, CREATE ANOTHER TABLE that will only import these Current/Previous Pairs for each GlobalID, but display them as one record each like this:
OR Is it a better design to Create 2 separate Tables AFTER CALCULATING GAP > GAP THRESHOLD, called tblPrevious & tblCurrent from the Temporary table like this?:
I need someone to point me in the right direction to have a better normalized design and achieve this using SQL query. Note: all the tables need to be generated dynamically everytime based on new data extract that is imported.
The below query gives error on Gap column and doesn't calculate Previous/Current:
PARAMETERS Threshold Long;
SELECT TEMPORARY.GlobalID, TEMPORARY.ItemID, TEMPORARY.[Version Date], IIf([TEMPORARY]![GlobalID]=
[TEMPORARY_1]![GlobalID],Max([TEMPORARY]![Version Date])-Min([TEMPORARY_1]![Version Date])=0,"Previous") AS Previous, TEMPORARY_1.ItemID, TEMPORARY_1.[Version Date], IIf([TEMPORARY]![GlobalID]=[TEMPORARY_1]![GlobalID],Max([TEMPORARY]![Version Date])-Min([TEMPORARY_1]![Version Date])>[Threshold],"Current") AS [Current], IIf(([TEMPORARY]![Version Date]-[TEMPORARY_1]![Version Date])>[Threshold],[TEMPORARY]![Version Date]-[TEMPORARY_1]![Version Date],"") AS GAP
FROM TEMPORARY, TEMPORARY AS TEMPORARY_1
GROUP BY TEMPORARY.GlobalID, TEMPORARY.ItemID, TEMPORARY.[Version Date], TEMPORARY_1.GlobalID, TEMPORARY_1.ItemID, TEMPORARY_1.[Version Date];
Any help would be most appreciated.
Will offer one more contribution - option with VBA code to get the Current/Previous pairs. This does require saving records to table. Tested and runs in a snap.
Sub GetGap()
Dim intTH As Integer, x As Integer, strGID As String
Dim rsT1 As DAO.Recordset, rsT2 As DAO.Recordset
CurrentDb.Execute "DELETE FROM Temp"
Set rsT1 = CurrentDb.OpenRecordset("SELECT * FROM Temporary ORDER BY GlobalID, ItemID DESC;")
Set rsT2 = CurrentDb.OpenRecordset("SELECT * FROM Temp;")
strGID = rsT1!GlobalID
x = 1
While Not rsT1.EOF
If strGID = rsT1!GlobalID Then
If x = 1 Then
rsT2.AddNew
rsT2!GlobalID = strGID
rsT2!CurItemID = rsT1!ItemID
rsT2!CurDate = rsT1![Version Date]
x = 2
ElseIf x = 2 Then
rsT2!GlobalID = strGID
rsT2!PreItemID = rsT1!ItemID
rsT2!PreDate = rsT1![Version Date]
x = 3
End If
If Not rsT1.EOF Then rsT1.MoveNext
Else
If x = 3 Then rsT2.Update
strGID = rsT1!GlobalID
x = 1
End If
If rsT1.EOF Then rsT2.Update
Wend
End Sub
Then a query can easily calculate the Gap and filter records.
SELECT Temp.GlobalID, Temp.CurItemID, Temp.CurDate, Temp.PreDate, Temp.PreItemID, [CurDate]-[PreDate] AS Gap
FROM Temp
WHERE ((([CurDate]-[PreDate])>Int([Enter Threshold])));
Or the code can be expanded to also calc the Gap and save only records that meet the threshold requirement, just a bit more complicated.
Review Allen Browne Subquery.
Requirements described in narrative differ from the title. Here are suggestions for both.
Queries pulling Current/Previous pairs.
Query 1:
SELECT [GlobalID], [ItemID] AS CurItemID, [Version Date] AS CurDate, (SELECT TOP 1 [Version Date] FROM Temporary AS Dupe WHERE Dupe.GlobalID=Temporary.GlobalID AND Dupe.ItemID < Temporary.ItemID ORDER BY Dupe.GlobalID, Dupe.ItemID DESC) AS PreDate, (SELECT TOP 1 [ItemID] FROM Temporary AS Dupe WHERE Dupe.GlobalID=Temporary.GlobalID AND Dupe.ItemID < Temporary.ItemID ORDER BY Dupe.GlobalID, Dupe.ItemID DESC) AS PreItemID
FROM [Temporary];
Query 2:
SELECT Query1.GlobalID, Query1.CurItemID, Query1.CurDate, Query1.PreDate, Query1.PreItemID, DateDiff("d",[PreDate],[CurDate]) AS Gap FROM Query1 WHERE ((([GlobalID] & [CurItemID]) In (SELECT TOP 1 GlobalID & CurItemID FROM Query1 AS Dupe WHERE Dupe.GlobalID = Query1.GlobalID ORDER BY GlobalID, CurItemID DESC))) AND DateDiff("d",[PreDate],[CurDate]) > Int([Enter Threshold]);
Final output:
GlobalID CurItemID CurDate PreDate PreItemID Gap
00109086 2755630 2/26/2015 3/11/2014 2130881 352
00114899 2785590 3/13/2015 3/25/2014 2093191 353
00154635 2755623 2/26/2015 4/4/2014 2176453 328
Here is query that addresses the requirement for Minimum/Maximum as stated in your title. Not as slow as the Current/Previous queries but if dataset gets significantly larger I expect it will get very slow.
SELECT Maximum.GlobalID, Maximum.ItemID AS MaxItem, Maximum.[Version Date] AS MaxItemDate, Minimum.ItemID AS MinItem, Minimum.[Version Date] AS MinItemDate, Maximum.[Version Date]-Minimum.[Version Date] AS Gap
FROM
(SELECT T1.GlobalID, T1.ItemID, T1.[Version Date] FROM [Temporary] AS T1 WHERE (((T1.ItemID) In (SELECT Min([ItemID]) AS MinItem FROM Temporary GROUP BY GlobalID)))) AS Minimum
INNER JOIN
(SELECT T1.GlobalID, T1.ItemID, T1.[Version Date] FROM [Temporary] AS T1 WHERE (((T1.ItemID) In (SELECT Max([ItemID]) AS MaxItem FROM Temporary GROUP BY GlobalID)))) AS Maximum
ON Minimum.GlobalID = Maximum.GlobalID
WHERE Maximum.[Version Date]-Minimum.[Version Date]>Int([Enter Threshold]);
Also, your dates are in international format. If you encounter issues with that, review Allen Browne International Dates
Task:
Append/edit the currently working code below to return only one row per patient, the maximum value of d1_10.xtransfer (datatype int) with the restriction that this row's d1_10.dstartdate <= glob_End_Date.
Caveats:
There are similar questions on StackOverflow and its sister sites. None that I have found have successfully helped with a resolution to this issue.
This is a medical EHR database, I can share code, but any discussion of results has to be general and exclude patient information.
I am replacing the SQL query within a pre-existing Excel spreadsheet to do something different. Excel pulls information from our database with an ODBC connection. Our database is using Ingres SQL which accepts most, but not all, of your typical SQL code varieties. It's possible that a piece of code will generally work in other flavors of SQL but not with the combo of Ingres and Excel. I've got the spreadsheet working and returning results, now it's about making some fixes by writing SQL code that works in this software.
Thus far:
With the currently working code below (no maximum d1_10.xtransfer restrictions) we return all rows with d1_10.dstartdate in the user selected date range and with the user selected d1_10.xinstitute. We want just the latest one. That is, the patient's row with either the maximum d1_10.dstartdate within the date range, or the maximum d1_10.xtransfer (index that counts up as they are added) within the date range.
Currently working code:
"SELECT " & _
"d1.xpid ""XPID"", " & _
"d0_v1.name_family ""NAME_FAMILY"", " & _
"d0_v1.name_given1 ""NAME_GIVEN1"", " & _
"d0_v1.name_given2 ""NAME_GIVEN2"", " & _
"d1.sex ""SEX"", " & _
"d1.birthdate ""DOB"", " & _
"d0_v1.hsp_pid, " & _
"c58.brief_name, " & _
"c73.cname, " & _
"date_trunc('day',d1_10.dstartdate) ""DSTARTDATE"", " & _
"date_trunc('day',d1_17.ddeath) ""DDEATH"" " & _
"FROM d1 " & _
"JOIN d0_v1 ON d1.xpid = d0_v1.xpid " & _
"JOIN d1_2 ON d1.xpid = d1_2.xpid " & _
"JOIN c58 ON d1_2.xmodality = c58.xcmodality " & _
"JOIN d1_10 ON d1.xpid = d1_10.xpid " & _
"JOIN c73 ON d1_10.xinstitute = c73.xcsite " & _
"JOIN d1_17 ON d1.xpid = d1_17.xpid " & _
"WHERE " & _
"d1_10.xinstitute = " & institute_index & " AND " & _
"d1_10.dstartdate >= '" & glob_Start_Date & " 00:00:00' and " & _
"d1_10.dstartdate <= '" & glob_End_Date & " 23:59:59' "
The closest I have gotten with code that runs from the excel spreadsheet is with this additional line in the WHERE clause:
d1_10.xtransfer = (SELECT MAX(d1_10.xtransfer) FROM d1_10 GROUP BY xpid)
With this additional line we now return only one row from each patient that has a d1_10.xtransfer within the date range. But if they have a row where d1_10.xtransfer is more recent than the date range, then they don't show up in the results at all.
With this line the code is taking MAX(d1_10.xtransfer) for each xpid before it applies the date restriction. By my logic we want it to do so after instead, but I have been unable to come up with code that runs that gets it any closer than this.
Thanks in advance. I'll keep this question updated with additional info below this page break.
Additional Info:
Per PaulM:
Yes, xpid is a patient ID index number, unique to each patient.
Added/edited line in WHERE clause to: "d1_10.xtransfer = (SELECT MAX(xtransfer) FROM d1_10 d1_10_b WHERE d1_10.xpid = d1_10_b.xpid AND d1_10_b.dstartdate <= '" & glob_End_Date & " 23:59:59') "
Patient Bob has transfers on both the 14th and 17th of June that fit the rest of the criteria.
When inputting a date range with an end date of Jun 17+, the spreadsheet correctly returns a row for Bob with his Jun 17 transfer.
When inputting a date range with an end date of Jun 14,15 or 16, the spreadsheet incorrectly does not return a row for Bob.
It seems as though it still takes the maximum xtransfer before restricting by date.
Per PaulM's comment:
I ran the subselect for a specific patient as follows:
Input:
SELECT MAX(xtransfer) FROM d1_10 d1_10_b WHERE d1_10_b.xpid = '2258' AND d1_10_b.dstartdate <= '20-apr-2016 23:59:59'
It outputted a value of MAX(xtransfer) = '48233'. This is correct.
So, when run in Visual SQL as its own statement, setting d1_10_b.xpid equal to a specific patient, it correctly pulls the maximum xtransfer from the date range. (There was a more recent xtransfer outside of the date range, and it still correctly displayed the maximum xtransfer from within the date range.)
I then tried running this exact same subselect in the where close for the spreadsheet. That is, I manually selected the same date range (which is being passed through as a variable correctly and successfully) but I subbed out d1_10.xpid = d1_10_b.xpid for d1_10_b.xpid = '2258'. This did not work. The spreadsheet did not show a row for this patient, seemingly because it still applies the MAX() function before it restricts by the date range in the subquery. And yet, the subquery works when run by itself.
Much appreciation for any further suggestions.
You need to add the date restriction in the subselect as well as the main query. Also I suspect the group by is wrong. By adding a group by you're making the subselect a list of patients xtransfer values with the largest value for each xpid (identifies a patient?). However that means if the row you're interested in from the main query happens to have an xtransfer value that matches the largest one belonging to a different xpid you're getting a false match.
What you really need is to add a join on xpid from the subselect back up to the main query. To do that you'll need a different correlation name e.g.
d1_10.xtransfer = (SELECT MAX(xtransfer)
FROM d1_10 d1_10_b
WHERE d1_10.xpid = d1_10_b.xpid
AND d1_10_b.dstartdate > = ... {as above} )
need to loop through date records in order to calculate the number of days worked. The number of dates varies from each person, they could have as few as one or as many as 11, ending with a calculation from the last dat in the sequence to the current days date.
Example of Data:
Employee No Date
4522 08/11/2011
4522 09/06/2011
4522 05/04/2013
4522 07/15/2013
4522 01/31/2014
So today is 04/29/2014, so from 01/31/2014 to 04/29/2014 is 88 days, 05/04/2013 to 07/15/2013 is 72 days and 08/11/2011 to 09/06/2011 is 26 days. Add those all together and you get a total of 186 days worked.
Again the number of dates will vary in each case.
Here's what I have so far...
Sub getActualEmployment(empID As Variant)
Dim strconnection, strSQL As String
Dim conn As ADODB.Connection
Dim tbl As ADODB.Recordset
Dim OptimumCode As String
Dim orghrdt As Date
Dim intNumDays As Integer
strSQL = "SELECT EmployeeID,EffectiveDate, OriginalHireDate FROM "
strSQL = strSQL & "EmploymentStatusChanges WHERE EmployeeID= '" & empID & "'"
strSQL = strSQL & " Order by EffectiveDate ASC"
Set tbl = New ADODB.Recordset
With tbl
Set .ActiveConnection = conn
.Source = strSQL
.LockType = adLockOptimistic
.CursorType = adOpenKeyset
.CursorLocation = adUseClient
.Open
End With
With tbl
On Error Resume Next
.MoveFirst
Do Until tbl.EOF
If tbl!OriginalHireDate = tbl!EffectiveDate Then
orghrdt = tbl!EffectiveDate
Else
intNumDays = CInt(DateValue(tbl!EffectiveDate) - orghrdt)
End If
.MoveNext
Loop
End With
End Sub
This is the whole function code, hopefully this makes better sense.
SELECT Employees.[Employee No], Employees.Action, Employees.DDate AS Start, Min(IIf([employees_1].[DDate]>=[employees].[ddate],[employees_1].[ddate])) AS [End], IIf([end] Is Not Null,[end],Now())-[start] AS Days
FROM Employees LEFT JOIN Employees AS Employees_1 ON Employees.[Employee No] = Employees_1.[Employee No]
WHERE (((Employees_1.Action)="term"))
GROUP BY Employees.[Employee No], Employees.Action, Employees.DDate
HAVING (((Employees.Action)="hire" Or (Employees.Action)="rehire"));
This query gives a list of all the hire events and the corresponding terms, with the days calculated for each. You can use a second query to sum the days by employee after you see how the 1st query turns out.
Note - this assumes that you have an alternating set of hire / termination events. If not, you may want to add some validations for this. Also, I think Date is reserved so I used DDate as the field name.
Firstly always make sure that you check the number of records to ensure that there is at least one before calling the MoveFirst method and iterating a recordset. It's better practice than relying on an error handler.
When you say that you want the number of days between the first two dates, are you referring to the dates in column "Date" in rows 0 and 1 or are you referring to dates in the same row in other columns that we can't see in the image? I assume that there are other date columns "OriginalHireDate" and "EffectiveDate".
Use the DateDiff function in VB6 to calculate the difference between dates. It's outlined here:
http://www.chennaiiq.com/developers/reference/visual_basic/functions/datediff.asp
intNumDays = DateDiff("d", CDate(tbl!EffectiveDate), orghrdt)
This will return the number of days between tbl!EffectiveDate and orghrdt. It will return a positive number if the latter is after the former and a negative number if the former is after the latter.
If you could clarify your table structure and my previous queries, I'll see whether I can help you further. You should be able to achieve what you what without the need to iterate through the whole recordset.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Ms Access Query: Concatenating Rows through a query
I have a table that has many columns, but two of interest: Order Number and Product Type. Currently the table has multiple Product Types per Order. If the customer ordered phone service, TV service and Internet service, then there would be three records - one for each service but all having the same order number. I want to create a reference table to store a concatenated string with all of the services the customer ordered. This way I can summarize my data using this more logical method. I'm using a standard Access 2010 database.
**Current table:**
Order Number | Product Types
100001 | TV
100001 | Phone
100001 | Internet
100002 | Phone
100003 | TV
100003 | Internet
Desired reference table
100001 | TV/Phone/Internet
100002 | Phone
100003 | TV/Internet
Allen Browne provides a function which you may find useful for this: Concatenate values from related records. Save that function's code in a standard module.
SELECT DISTINCT
[Order Number],
ConcatRelated("[Product Types]",
"YourTable",
"[Order Number] = " & [Order Number],
"[Product Types]",
"/"
) AS All_Product_Types
FROM YourTable;
I tested that query in Access 2007 with your sample data saved in a table named "YourTable". It returned the results you asked for. However, this only works from within an Access session. If you wanted to run this query from outside Access (like from ASP), user-defined functions are not available, so you would get an error about ConcatRelated() not recognized.
So you can use a query to retrieve the concatenated values whenever you need them. However if you store those concatenated values, they can quickly be out of sync with changes to the base table's data.
If I understand the question, you're asking how to get the order numbers of just those orders who have TV, AND phone, AND internet. If you're just interested in those order numbers you could run a query like:
SELECT Distinct Table1.OrderNumber
FROM (Select OrderNumber from Table1 where [product types]= "Internet") AS i
INNER JOIN ((Select OrderNumber from Table1 where [product types]="Phone") AS p
INNER JOIN ((Select OrderNumber from Table1 Where [product types]= "TV") AS tv
INNER JOIN Table1 ON tv.OrderNumber = Table1.OrderNumber) ON p.OrderNumber = Table1.OrderNumber) ON i.OrderNumber = Table1.OrderNumber;
As was pointed out by onedaywhen in an early post on SO, this is easier with ADO:
Sample query:
SELECT [Order Number],
ConcatADO("SELECT [Product Types] FROM Orders
WHERE [Order Number]=" & [Order Number],", "," : ") AS Cat
FROM Orders
GROUP BY [Order Number], 2;
Function using ADO
Function ConcatADO(strSQL As String, strColDelim, _
strRowDelim, ParamArray NameList() As Variant)
Dim rs As New ADODB.Recordset
Dim strList As String
On Error GoTo Proc_Err
If strSQL <> "" Then
rs.Open strSQL, CurrentProject.Connection
strList = rs.GetString(, , strColDelim, strRowDelim)
strList = Mid(strList, 1, Len(strList) - Len(strRowDelim))
Else
strList = Join(NameList, strColDelim)
End If
ConcatADO = strList
Exit Function
Proc_Err:
ConcatADO = "***" & UCase(Err.Description)
End Function
You should not create a reference table that concatenates records. That is denormalizing the database.
You can try a crosstab query like below, but I have not tested it. You can read here for more information.
TRANSFORM First([Product Types]) AS Product
SELECT [Order Number], First([Product Types])
FROM CurrentTable
GROUP [Order Number]