Concatenating Multiple columns in an Access table to one specific row - sql

I have been on the web searching for answers and I just can not find one that works (I'm sure it is something I am not doing right)
I have a table in Access called TBL003_Combined Data that has the following columns:
UPLOADED, REF ID, QTY, PART NUMBER, ITEM DESCRIPTION, SHIP TO
4/8/2015, 123, 20, 9125xtr, sample item, XYZ Company, 789 Address Lane, Somewhere,US 159632
4/8/2015, 123, 16, 22578xtz, sample item2, XYZ Company, 789 Address Lane, Somewhere,US 159632
4/8/2015, 123, 8, 7758rty, sample item3, XYZ Company, 789 Address Lane, Somewhere,US 159632
What I am trying to do is for each unique [REF ID], I want to concatenate the QTY, [PART NUMBER], [ITEM DESCRIPTION] & [SHIP TO] to a new column called [CS_ITEM DESCRIPTION].
I have tried the following in Allen Brown's site:
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 DISTINCT " & 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 my query I've used the following:
SELECT DISTINCT
[REF ID],
ConcatRelated("[QTY],[PART NUMBER], [ITEM DESCRIPTION], [SHIP TO]",
"[TBL003_Combined Data]",
"[REF ID] = " & [REF ID],
"("[QTY],[PART NUMBER], [ITEM DESCRIPTION], [SHIP TO]",
"/"
) AS CS_ITEM DESCRIPTIONS
FROM [TBL003_Combined Data];
and I keep getting the following error:
"Syntax error (missing operator) in query expression...."
then it list the entire SQL I'm referencing above (Select Distinct). Any help in pointing me in the right direction or advising why I am doing wrong (as I'm certain it's me) will be greatly appreciated.
added: The result I'm trying to reach is for the data to come out as follows:
UPLOADED, REF ID, CS_ITEM DESCRIPTION
4/8/2015, 123, 20 / 9125xtr / sample item / 16 / 22578xtz /sample item2 / 8 / 7758rty / sample item3 / XYZ Company, 789 Address Lane, Somewhere,US 159632

Try this:
SELECT distinct [REF ID],
[QTY] + ' ' + [PART NUMBER] + ' ' + [ITEM DESCRIPTION] + ' ' + [SHIP TO]
AS 'CS_ITEM DESCRIPTIONS'
FROM [TBL003_Combined Data];

Related

Microsoft Office Access - Median function - Too few parameters

I am trying to use this code to calculate median from my query which has these criteria:
<[Form]![testForm2]![crit1] And >[Form]![testForm2]![crit2] and <[Form]![testForm2]![Age1] And >[Form]![testForm2]![Age2]
without these criteria function works well and gives for every task median based on "MP", however when I put in there my criteria I receive error:
error - Too few parameters. Expected 4 and then it says 'Object Variable or With block not set'
my input: DMedian("MP";"testForm2";"[TASK]= '" & [TASK] & "'")
*even when the Form is open it end up with the error.
*I probably need to find a different way to filter this query from the form, but I don't know how
Public Function DMedian(FieldName As String, _
TableName As String, _
Optional Criteria As Variant) As Variant
' Created by Roger J. Carlson
' http://www.rogersaccesslibrary.com
' Terms of use: You may use this function in any application, but
' it must include this notice.
'Returns the median of a given field in a given table.
'Returns -1 if no recordset is created
' You use this function much like the built-in Domain functions
' (DLookUp, DMax, and so on). That is, you must provide the
' 1) field name, 2) table name, and 3) a 'Where' Criteria.
' When used in an aggregate query, you MUST add each field
' in the GROUP BY clause into the into the Where Criteria
' of this function.
' See Help for more on Domain Aggregate functions.
On Error GoTo Err_Median
Dim db As DAO.Database
Dim rs As DAO.Recordset
Dim strSQL As String
Dim RowCount As Long
Dim LowMedian As Double, HighMedian As Double
'Open a recordset on the table.
Set db = CurrentDb
strSQL = "SELECT " & FieldName & " FROM " & TableName
If Not IsMissing(Criteria) Then
strSQL = strSQL & " WHERE " & Criteria & " ORDER BY " & FieldName
Else
strSQL = strSQL & " ORDER BY " & FieldName
End If
Set rs = db.OpenRecordset(strSQL, dbOpenDynaset)
'Find the number of rows in the table.
rs.MoveLast
RowCount = rs.RecordCount
rs.MoveFirst
'Determine Even or Odd
If RowCount Mod 2 = 0 Then
'There is an even number of records. Determine the low and high
'values in the middle and average them.
rs.Move Int(RowCount / 2) - 1
LowMedian = rs(FieldName)
rs.Move 1
HighMedian = rs(FieldName)
'Return Median
DMedian = (LowMedian + HighMedian) / 2
Else
'There is an odd number of records. Return the value exactly in
'the middle.
rs.Move Int(RowCount / 2)
'Return Median
DMedian = rs(FieldName)
End If
Exit_Median:
'close recordset
rs.Close
Exit Function
Err_Median:
If Err.number = 3075 Then
DMedian = 0
Resume Exit_Median
ElseIf Err.number = 3021 Then
'EOF or BOF ie no recordset created
DMedian = -1
Resume Exit_Median
Else
MsgBox Err.Description
Resume Exit_Median
End If
End Function
The parameter separation character is comma and you are using a semi-colon
CHANGE:
DMedian("MP";"testForm2";"[TASK]= '" & [TASK] & "'")
TO:
DMedian("MP", "testForm2", "[TASK]= '" & [TASK] & "'")
Solution was to refer the text boxes in SQL declaration, Thank you guys
like this:
HAVING (((Data.[REV]< " & Me.crit1 & ") And (Data.[REV])>" & Me.crit2 & ") AND ((Reg.Age)<" & Me.Age1 & " And (Reg.Age)>" & Me.Age2 & " " & SQLcritComplete & "));"
NOT like this:
"HAVING (((Data.[REV]<[Form]![testForm2]![crit1]) And (Data.[REV])>[testForm2]![crit2]) AND ((Reg.Age)<[Form]![testForm2]![Age1] And (Reg.Age)>[Form]![testForm2]![Age2] & SQLcritComplete & "));"

Append to table using unbound textbox

I am trying to append two data points to a table using unbound textboxes. I can get one to populate properly, but the other one is coming over blank.
For this example the Criteria1 = 1 and Criteria2 = 9/24/19
Here is my code:
Dim StrSQL As String
Dim db As DAO.Database
Dim qdf As DAO.QueryDef
Set db = Application.CurrentDb
Set qdf = db.QueryDefs("3 - GRUpload")
Dim Criteria1 As String
Dim Criteria2 As String
Criteria1 = Me!GRValue
Criterial2 = Me!GRDate
StrSQL = "Insert Into [*Master Records - 2 - GRs] ([GR Value], [GR Date]) Values(" & Criteria1 & ", " & Criteria2 & ")"
qdf.SQL = StrSQL
I attached a picture of the resulting query, but this is SQL if that's more helpful:
INSERT INTO [*Master Records - 2 - GRs] ([GR Value], [GR Date])
Select 1 As Exp1, Criteria2 AS Expr2;
I have tried several variations of the code, including:
Values(""" & Criteria1 & """, """ & Criteria2 & """)"
Which results in:
INSERT INTO [*Master Records - 2 - GRs] ([GR Value], [GR Date])
Select "1" As Exp1, "" AS Expr2;
So I'm at a loss... Could one of you point me in the right direction?
Thank you!
Date/time type field requires # delimiter for parameters. Text type use apostrophe (or doubled quote), numbers none. Try:
StrSQL = "Insert Into [*Master Records - 2 - GRs] ([GR Value], [GR Date]) " & _
Values(" & Criteria1 & ", #" & Criteria2 & "#)"
Strongly advise not to use spaces nor punctuation/special characters in naming convention.

Using Input from Worksheet in a Query in a Macro

I am trying to take the percent column, column 3, from the "input" file and use that to take a discount on a price and put that price in the output file, one by one in column 7.
I pass the SQL connection to a function, a UPC value that looks up information in a database, and then the percent value (a Double) as input.
However, I keep getting the error "Incorrect syntax near the keyword percent". I have tried renaming the percent variable, and also using the Val() function (as you can see in the code).
If I take the Val() out, I get a type mismatch error
Basically: I cannot figure out how to use an input for "percent" such as .10 in my Query.
For i = 1 To 381
wrkb.Worksheets("Output").Cells(i + 1, 2).CopyFromRecordset extractInfo(cnn, wrkb.Worksheets("Input").Cells(i, 2).Value, Val(wrkb.Worksheets("Input").Cells(i, 3).Value))
Next i
Function extractInfo(cnn As ADODB.Connection, upc As String, percent As Double) As ADODB.Recordset
'Initializes variables
Dim rst As New ADODB.Recordset
Dim StrQuery As String
'The query to run, feed the UPC value you acquired to then get all the other variables
StrQuery = "SELECT 'N' as Division, zzeupcnr.style as Style, color_code as Color, ' ' as label_code, dimension as Dimension, ROUND((a_price * (1.00 - percent)), 2), ret_price " & _
"FROM zzeupcnr JOIN zzxstylr " & _
"ON zzeupcnr.style = zzxstylr.style " & _
"WHERE upc = '" & upc & "'"
'Performs the actual query
rst.Open StrQuery, cnn
Set extractInfo = rst 'Stores result
You're using percent in your query string as a string.
If you want to use the variable value, you need to do this:
StrQuery = "SELECT 'N' as Division, zzeupcnr.style as Style, color_code as Color, ' ' as label_code, dimension as Dimension, ROUND((a_price * (1.00 - " & percent & ")), 2), ret_price " & _
"FROM zzeupcnr JOIN zzxstylr " & _
"ON zzeupcnr.style = zzxstylr.style " & _
"WHERE upc = '" & upc & "'"
Note the " & percent & "

Access Split column data w semi-colon into normalize table structure

I have a table, which was pulled out of some XML data. I'm trying to do a cross reference, so I can line out a plan for organizing the data. This 1 table has a list of variables. Fields of different data types, computations, as well as dialogs. One of the columns has options. If the data type of the variable is a dialog, its options has a list of variables, separated by a semi-colon.
So the main table has a structure like so:
For the dialog records I need to look through their options column and insert records into a normalized table. For each field, in that column, I want to add a record with that dialog name, and the ID of the row in that table (I added a PK to the table). For instance, in the dialog record, Options column, there is a field in there called BusinessName TE. I need to search this main table for the PK ID of the row that has a variable name of the same. I need to put that record's ID with the name of the dialog, and insert both into a new table I set up. This will create a cross reference for me, so I can know which variables are being used by which dialogs.
I appreciate any help anyone can give. I see stuff about using a split function, arrays and looping through to get each value, but the examples I'm finding are for strings, not a column in a table.
Thanks!
Edit: Adding in the VBA code I'm working with. I attached it to a button on a form, just so I could click to run it.
Private Sub RunParse_Click()
Dim db As DAO.Database
Dim rs As Recordset
Set db = CurrentDb()
Dim sqlStr, insertSQL, arrayVal As String
Dim TestArray As Variant
Dim Options As String
Dim Dialog As String
Dim FieldName As Long
Dim i As Integer
sqlStr = "SELECT [MASTER Fields].Options,[MASTER Fields].[Variable Name] FROM [MASTER Fields] WHERE ((([MASTER Fields].[Variable Type])='dialog'));"
Set rs = db.OpenRecordset(sqlStr)
rs.MoveLast
rs.MoveFirst
Do While Not rs.EOF
Options = rs.Fields(0)
Dialog = rs.Fields(1)
If InStr(Options, ";") Then
TestArray = Split(Options, ";")
For i = 0 To UBound(TestArray) - LBound(TestArray) + 1
If TestArray(i) <> "" Then
arrayVal = TestArray(i)
FieldName = DLookup("ID", "MASTER Fields", "[Variable Name] = " & "'" & arrayVal & "'")
insertSQL = "INSERT INTO FieldTemplatesUse(FID, TemplateAK) " _
& "VALUES(""" & FieldName & """, """ & Dialog & """)"
DoCmd.RunSQL (insertSQL)
End If
Next i
End If
rs.MoveNext
Loop
End Sub
right now on the line that says
If TestArray(i) <> "" Then
creates an error ""
If anyone can help, I'd really appreciate it!
Another Edit:
Parfait figured out my issue. I'm posting the final code I am using, in case it helps someone else! p.s. I added a condition to check if the dlookup is successful, and trap failures in a failures table. That way I can check those out afterward.
Private Sub RunParse_Click()
Dim db As DAO.Database
Dim rs As Recordset
Set db = CurrentDb()
Dim sqlStr, insertSQL, arrayVal As String
Dim TestArray As Variant
Dim Options As String
Dim Dialog As String
Dim FieldName As Long
Dim i As Integer
sqlStr = "SELECT [Master Fields].Options,[Master Fields].[Variable Name] FROM [Master Fields] WHERE ((([Master Fields].[Variable Type])='dialog'));"
Set rs = db.OpenRecordset(sqlStr)
rs.MoveLast
rs.MoveFirst
Do While Not rs.EOF
Options = rs.Fields(0)
Dialog = rs.Fields(1)
If InStr(Options, ";") Then
TestArray = Split(Options, ";")
For i = 0 To UBound(TestArray) - LBound(TestArray)
If TestArray(i) <> "" Then
arrayVal = TestArray(i)
If Not (IsNull(DLookup("ID", "Master Fields", "[Variable Name] = " & "'" & arrayVal & "'"))) Then
FieldName = DLookup("ID", "Master Fields", "[Variable Name] = " & "'" & arrayVal & "'")
insertSQL = "INSERT INTO FieldTemplatesUse(FID, TemplateAK) " _
& "VALUES(""" & FieldName & """, """ & Dialog & """)"
DoCmd.RunSQL (insertSQL)
'MsgBox "Adding ID = " & FieldName & "for Dialog: " & Dialog & "Now"
Else
insertSQL = "INSERT INTO tblFieldsNotFound(Dialog, FieldNotFound) " _
& "VALUES(""" & Dialog & """, """ & arrayVal & """)"
DoCmd.RunSQL (insertSQL)
End If
End If
Next i
End If
rs.MoveNext
Loop
MsgBox "All Done!"
End Sub

Parameter error when using VB Concatenate function

I'm using the following VBA from a friend that works quite well for concatenating items in MS Access.
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
I call this function successfully from the following query:
INSERT INTO tblData ( SubjectNumber, RECDATE, RecordedDoses, DoseTimes, FoodType, ProgrammingComments )
SELECT d.SubjectNumber, d.RECDATE, Count(d.RECTIME) AS RecordedDoses, ConcatRelated("RECTIME", "qryDump2", "SubjectNumber= """ & d.[SubjectNumber] & """" & " AND RECDATE=" & FORMAT(d.RECDATE, "\#yyyy-m-d\#")) AS DoseTimes, ConcatRelated("FoodType", "qryDump2", "SubjectNumber= """ & d.[SubjectNumber] & """" & " AND RECDATE=" & FORMAT(d.RECDATE, "\#yyyy-m-d\#")) AS FoodType, d.Visit AS ProgrammingComments
FROM qryDump2 AS d
GROUP BY d.SubjectNumber, d.RECDATE, d.Visit
HAVING Count(d.RECTIME)<2 Or Count(d.RECTIME)>2
ORDER BY d.RECDATE;
The query above references several tables and queries. The issue is, when my criteria is a specific subject, e.g. "1011002", the concatenate function has no problem running. However, when the criteria is anything else, e.g. Prompt criteria, referencing a text box, etc, I get the fun "Error 3061: Too few parameters. Expected 1. If I switch my criteria back to a string, e.g. "1011002" it works again. When using prompt criteria, if I type the same item in, i.e. 1011002, the error appears again.
What am I missing?
Edit: The query that is called a few items down the line that references the criteria I mentioned above is as follows:
SELECT tblDump.SubjectNumber, IIf(tblDump.SD_DAY=1,tblDump.RECDATE,tblDump.RECDATE-1) AS RECDATE, IIf(tblDump.DRUG_Q1=1,tblDump.RECTIME,tblDump.DRUG_Q6) AS RECTIME, tblDump.FoodType, IIf(IIf(tblDump.SD_DAY=1,tblDump.RECDATE,tblDump.RECDATE-1)=tblL.DiscontDate,"DayOfDiscontinuation",IIf(IIf(tblDump.SD_DAY=1,tblDump.RECDATE,tblDump.RECDATE-1)=tblL.CompletionDate,"CompletionDate",IIf(IIf(tblDump.SD_DAY=1,tblDump.RECDATE,tblDump.RECDATE-1)=tblL.[2],"Visit2"))) AS Visit
FROM tblDump LEFT JOIN tblL ON tblDump.SubjectNumber = tblL.SubjectNumber
WHERE tblDump.SubjectNumber=Forms![frm]![test];
The where statement, when I use an actual value, e.g. "1011002" (subject number is text and not a number even though the example I gave is a number), the concatenate function works. When I use what is above, i.e. referencing a form field, I get the aforementioned error.
The where clause isn't checking to see if the text has spaces, maybe trim the form data before putting it into the function call and see if that stops your code from creating an empty where clause in the sql.