DMax within Insert Into SQL statement (not working) - sql

I've got a piece of VBA code that pulls data in from a linked table and appends some date columns based on using the DMax function to look up the most recent transaction dates based on SKU and transaction type. I'm getting the following error:
For some reason the DMax function is not seeing the data properly from the SKU field that is in the select statement.
SQLstr = "Insert Into TEMP_ONHAND Select " & _
"COMPANY, WHSE, WHSEDESC, ITEM, ITEMDESC, ESTCOSTPRICE, INVONHAND, CONSIGNINVONHAND, " & _
"QUANTITYINTRANSIT, QTY, COST, LASTINVTRANS, SUPPLIERID, SUPPLIER, " & _
"BUYER, BUYERNAME, PLANNER, PLANNERNAME, BUYFROMBP, BUYFROMBPNAME, " & _
"[COMPANY] & '-' & [WHSE] & '-' & [ITEM] AS SKU, " & _
"Left([WHSEDESC],3) AS TYPE, " & _
"#" & DMax("[TRANSDATE]", "[TEMP_HISTORY]", "[SKU]='" & [SKU] & "' AND [TRANSTYPE] = 3") & "# AS LAST_RCPT, " & _
"#1/1/1950# AS LAST_ISSUE, " & _
"#1/1/2000# AS LAST_ADJUST, " & _
"'TEST' AS TRAN_RANGE, " & _
"'TEST' AS ADJ_RANGE " & _
"From PARTS_ONHAND;"
MsgBox SQLstr
Application.CurrentDb.Execute SQLstr
If I replace the & [SKU] & in the DMax function with an actual text string of a SKU, this code works fine. I'm wondering if the syntax needs to be different somehow within the DMax function in order to reference a field from the select portion of the statement?

The & [SKU] & code is not referencing calculated SKU field of SELECT portion of constructed SQL statement. This concatenation takes place within the VBA procedure, not the SQL statement. Therefore, VBA looks for [SKU] and can't find anything. In fact, that entire DMax() expression is executed in this VBA procedure and if it did succeed it would return a single value for concatenation and every record pulled by the SELECT would have it. If you want to reference calculated SKU field as input to DMax(), then DMax() expression must be embedded in constructed SQL statement.
Embedding domain aggregate functions with dynamic arguments within SQL constructed in VBA is tricky when text fields are the criteria. Try:
"# & DMax('[TRANSDATE]', '[TEMP_HISTORY]', '[TRANSTYPE] = 3 AND [SKU]=' & Chr(39) & [SKU] & Chr(39)) & # AS LAST_RCPT, " & _
Or build a SELECT query object which includes DMax() function then call that object by the VBA procedure.
SQLstr = "Insert Into TEMP_ONHAND Select * FROM queryName"
Or don't save aggregate data, calculate it when needed.

Try this:
SQLstr = "Insert Into TEMP_ONHAND Select " & _
"COMPANY, WHSE, WHSEDESC, ITEM, ITEMDESC, ESTCOSTPRICE, INVONHAND, CONSIGNINVONHAND, " & _
"QUANTITYINTRANSIT, QTY, COST, LASTINVTRANS, SUPPLIERID, SUPPLIER, " & _
"BUYER, BUYERNAME, PLANNER, PLANNERNAME, BUYFROMBP, BUYFROMBPNAME, " & _
"[COMPANY] & '-' & [WHSE] & '-' & [ITEM] AS SKU, " & _
"Left([WHSEDESC],3) AS TYPE, " & _
"DMax(""[TRANSDATE]"", ""[TEMP_HISTORY]"", ""[SKU] = '"" & [SKU] & ""' AND [TRANSTYPE] = 3"") AS LAST_RCPT, " & _
"#1/1/1950# AS LAST_ISSUE, " & _
"#1/1/2000# AS LAST_ADJUST, " & _
"'TEST' AS TRAN_RANGE, " & _
"'TEST' AS ADJ_RANGE " & _
"From PARTS_ONHAND;"

Related

Write multiple occurences under single cell in SQL for VBA

I am working on SQL for VBA.
Usually, if we have multiple occurrences of the desired condition, each of the occurrences will be written on different cells, like the code below:
"SELECT CPID " & _
"FROM LCOND_LAST " & _
"WHERE WELL ='" & sht1.Cells(i + 3, 8) & "' " & _
"ORDER CPID"
Which will gives output:
Notice that there are 2 cells to write two occurrences.
My question is, can we just write them on single cells only?
Is there any function that allows us to do so?
You can use the DISTINCT as follows:
"SELECT WELL, CPID " & _
"FROM LCOND_LAST " & _
"WHERE WELL ='" & sht1.Cells(i + 3, 8) & "' " & _
"ORDER BY PSWELLCOND_LAST.CPID"
DISTINCT is used to filter duplicate rows
Learn more about DISTINCT from here.
-- Update
You can use the CHR(10) -- newline and aggregate it as follows:
"SELECT LISTAGG(CPID, CHR(10)) WITHIN GROUP (ORDER BY CPID) " & _
"FROM LCOND_LAST " & _
"WHERE WELL ='" & sht1.Cells(i + 3, 8) & "' "

VB.Net: Escape singles quotes in query string that uses a variable with single quotes

A few of the records that my program is processing are creating a record in the log table that reads:
instruments: Incorrect syntax near 's'. Unclosed quotation mark after the character string ')))'.
The code uses an inline query that concatenates the value of a string variable to the WHERE clause in the SELECT and SubQueries.
Code:
SQL = "SELECT instrument_id, description, sub_category_of, meta_instrument" _
& " FROM instruments " _
& " WHERE (instrument_id IN " _
& " (SELECT instrument_id " _
& "FROM instruments " _
& "WHERE (description = '" & strn & "'))) " _
& "OR (instrument_id IN " _
& " (SELECT sub_category_of " _
& " FROM instruments AS instruments_1 " _
& " WHERE (description = '" & strn & "'))) " _
& "OR (instrument_id IN " _
& " (SELECT meta_instrument " _
& " FROM instruments AS instruments_1 " _
& " WHERE (description = '" & strn & "')))"
The actual query that gets executed against sql server:
SELECT instrument_id, description, sub_category_of, meta_instrument _
FROM instrument_ref
WHERE (instrument_id IN
(SELECT instrument_id
FROM instruments
WHERE (description = 'Women's Choir')))
OR (instrument_id IN
(SELECT sub_category_of
FROM instruments AS instruments_1
WHERE (description = 'Women's Choir')))
OR (instrument_id IN
(SELECT meta_instrument
FROM instruments AS instruments_1
WHERE (description = 'Women's Choir')))
I would like to ask for help in how the single quote can be handled so that this error can be corrected. Do I escape it in the 'strn' variable, or do I do it inside the inline query?
Thank you much.
As suggested, use parameters:
SQL = "SELECT instrument_id, description, sub_category_of, meta_instrument" _
& " FROM instruments " _
& " WHERE (instrument_id IN " _
& " (SELECT instrument_id " _
& "FROM instruments " _
& "WHERE (description = #description))) " _
& "OR (instrument_id IN " _
& " (SELECT sub_category_of " _
& " FROM instruments AS instruments_1 " ... etc
Then, when you construct the SqlCommand object with this SQL, use the command object's ".Parameters.AddWithValue()" method to add a parameter called "#description" and the appropriate value.
This, by the way, prevents someone from causing havoc by entering a description of "; drop table instruments;".

where msaccess vba

why the following msaccess vba statement fails when add the where statement?
I want to check if the field has value
Set rsMySet = CurrentDb.OpenRecordset("PivotTblInvDepts")
'Start the count at the position number of the first column-oriented field
'Remember that Recordsets start at 0
For i = 3 To rsMySet.Fields.Count - 1
'*********************************************************************************************************************
'Use the recordset field.name property to build out the SQL string for the current field
strSQL = "INSERT INTO TabularDepts ([Depts], [Code], [Description], [Qty])" & _
"SELECT" & "'" & rsMySet.Fields(i).Name & "'" & " AS Dept," & _
"[PivotTblInvDepts].[Code],[PivotTblInvDepts].[Description]," & _
"[" & rsMySet.Fields(i).Name & "]" & _
"FROM PivotTblInvDepts;" & _
"WHERE" & " (rsMySet.Fields(i).Name)>0"
Try removing the ; in FROM PivotTblInvDepts;.
Also you need space at the end of the previous line. "[" & rsMySet.Fields(i).Name & "]" & _ should be "[" & rsMySet.Fields(i).Name & "] " & _. Likewise, make sure to add a space so that you do no result in FROM PivotTblInvDeptsWHERE
Your current SQL reads something like this
INSERT INTO TabularDepts ([Depts], [Code], [Description], [Qty])
SELECT '<data>' As Dept,
[PivotTblInvDepts].[Code],[PivotTblInvDepts].[Description],
[<data>]
FROM PivotTblInvDepts;
WHERE <condition>
After removing the ;, the insert will be cleaner.

DATE Variable not inserting values properly

I have a macro that opens a MS Project file and copies the content itself in an Access table. I make it through Excel because afterwards I need to make some queries and copy the results into some cells.
This code below creates or drops the table:
Dim dbX As DAO.Database
If Err.Number = 0 Then
dbX.Execute ("DROP TABLE " & dbName & ";")
End If
dbX.Execute ("CREATE TABLE " & dbName & " ([ID] INTEGER, [TaskID] INTEGER, [Milestone] TEXT(3), [TaskName] TEXT(255), " & _
"[pComplete] TEXT(10), [Start] DATE, [Finish] DATE, [BaselineStart] DATE, [BaselineFinish] DATE, " & _
"[ActualStart] DATE, [ActualFinish] DATE);")
Err.Clear
This fills the table using the project fields:
dBquery = "INSERT INTO " & tName & "(ID, TaskID, Milestone, TaskName, pComplete, Start, Finish, BaselineStart, BaselineFinish, " & _
"ActualStart, ActualFinish)" & _
" VALUES (" & t.ID & ", " & t.UniqueID & ", '" & t.GetField(pjTaskMilestone) & "', '" & t.Name & "', '" & t.GetField(pjTaskPercentComplete) & _
"', " & RetrieveDate(t.Start) & ", " & RetrieveDate(t.Finish) & ", " & RetrieveDate(t.BaselineStart) & ", " & _
RetrieveDate(t.BaselineFinish) & ", " & RetrieveDate(t.ActualStart) & ", " & RetrieveDate(t.ActualFinish) & ");"
dB.Execute dBquery
RefreshDatabaseWindow
This is the function used to retrieve the date fields:
Function RetrieveDate(D As Variant) As Variant
If D = "NA" Then
RetrieveDate = "NULL"
Else
RetrieveDate = "#" & D & "#"
End If
End Function
The problem that I have is that when the code finds an ambiguous date, uses the American format, so when I try to run queries, the results are not correct.
For example, here I have a task with its dates and everything:
Whatever the date format I use it spins the date or it just doesn't insert the dates into the DB.
For example, in this table, the dates are inserted in decimal format. The same task in the database is:
In this image above we can see fewer fields because I've just taken the ones that I need.
So, if for example I make a query to retrieve the date in 'dd/mm/yyyy' format this same task, I get:
SELECT FORMAT(Start, "dd/mm/yyyy"), FORMAT(Finish, "dd/mm/yyyy")
FROM ow18_072014
WHERE TaskID = 202;
I have tried to convert the format to yyyy/mm/dd but the dates are not pasted into the table.
Another conversion I have tried is to change date format from Project but now Access changes some dates without any sense: a date equal to 20 Jun 2014 in MS Project becomes 15/11/2013 in MS Access.
You do not give us much information, and in the future, if you want people to actually have a chance of helping you, you have to put more effort in your question: give us some code you tried, some data example, etc.
Anyway, the issue is that by default, Access interprets literal dates as #mm/dd/yyyy#, except when it's unambiguous, like #25/12/2014#.
There are 2 ways to solve this issue: if you pass a litteral date to Access, use the #yyyy/mm/dd# ISO format instead because it's unambiguous and it will work in every locale.
Alternatively, convert your date to a decimal value and pass that to your Access date field instead, like CDec(myDate), will pass something like 41851.3465625 to Access and it will work.
The GetField method of the Task object returns a string value. For date fields, it returns the value in the format selected by the user (or set by the DefaultDateFormat property of the application object).
The simplest solution is to use the explicit properties of the Task object instead of the GetField method.
Modify your SQL statement to something like this:
dBquery = "INSERT INTO " & t.Name & "(ID, TaskID, Milestone, TaskName, pComplete, Start, Finish, BaselineStart, BaselineFinish, " & _
"ActualStart, ActualFinish)" & _
" VALUES (" & t.ID & ", " & t.UniqueID & ", '" & t.Milestone & "', '" & t.Name & "', '" & t.PercentComplete & _
"', " & RetrieveDate(t.Start) & ", " & RetrieveDate(t.Finish) & ", " & RetrieveDate(t.BaselineStart) & ", " & _
RetrieveDate(t.BaselineFinish) & ", " & RetrieveDate(t.ActualStart) & ", " & RetrieveDate(t.ActualFinish) & ");"

SQL Query works in MS-Access but cannot implement it in vb.net form

The block of code immediately following (given to me by a stackoverflow solver) works perfectly in MS-Access. I'm trying to convert it to work in a vb.net form accessing the very same MS-Access database. I get an error and cannot see my mistake. Are there any vb.net coders that can see what I'm doing wrong. The first block of code works in MS-Access and is the code I'm trying to convert. And the second block of code is my conversion attempt.
SELECT at.animalID, amt.milestoneType
FROM
animals_Table at
LEFT JOIN
(
SELECT animalID, milestoneType
FROM animalMilestones_Table
WHERE milestoneType = 'Intake'
) amt
ON at.animalID = amt.animalID
Now, my conversion attempt:
dim selectAnimal as string
selectAnimal = "SELECT at.animalID, amt.milestoneType" & _
" FROM animals_Table at" & _
" LEFT JOIN" & _
" (" & _
" SELECT animalID, milestoneType" & _
" FROM animalMilestones_Table" & _
" WHERE milestoneType = '" & "Intake" & "'" & _
" ) amt" & _
" ON at.animalID = amt.animalID"
The error code I get is
!ErrorInfo.GetDescription failed with E_FAIL(0x80004005)
It appears that ACE.OLEDB doesn't like at as a table alias. Try this instead
Dim selectAnimal As String
selectAnimal = "SELECT atbl.animalID, amtbl.milestoneType" & _
" FROM animals_Table atbl" & _
" LEFT JOIN" & _
" (" & _
" SELECT animalID, milestoneType" & _
" FROM animalMilestones_Table" & _
" WHERE milestoneType = '" & "Intake" & "'" & _
" ) AS amtbl" & _
" ON atbl.animalID = amtbl.animalID"