MS Access currentdb.excute has different result than Docmd.RunSQL - ms-access

I use VBA to run an INSERT INTO ... SELECT... SQL query with Currentdb.Execute command. However, I have trouble with the result. There are some rows missing the data.
The result is correct when using Docmd.RunSQL with the same SQL, but I don't want the warning message for inserting data into the table.
I also tried using only the SELECT... with Currentdb.Execute and print the result on the debug window. The result is correct, no missing data.
Here's my code:
strsql = strsql & "INSERT INTO tempLineItems (OrderNo, PositionNo, PartNo, [Description], PlannedDeliveryDate, Qty, Unit, Price, Curr, txta, LineItemText, Discount, Tax) "
strsql = strsql & "SELECT dbo_ttdsls041600.t_orno, dbo_ttdsls041600.t_pono, dbo_ttdsls041600.t_item, IIF(dbo_ttipcs021600.t_dsca is null,dbo_ttiitm001600.t_dsca,dbo_ttipcs021600.t_dsca) AS t_dsca, dbo_ttdsls041600.t_ddta, dbo_ttdsls041600.t_oqua, dbo_ttdsls041600.t_cups, dbo_ttdsls041600.t_pric, dbo_ttdsls040600.t_ccur, dbo_ttdsls041600.t_txta, Null AS LineItemText, dbo_ttdsls041600.t_disc_1, dbo_ttdsls041600.t_cvat "
strsql = strsql & "FROM dbo_ttdsls040600 INNER JOIN ((dbo_ttipcs021600 RIGHT JOIN dbo_ttdsls041600 ON (dbo_ttipcs021600.t_item = dbo_ttdsls041600.t_item) AND (dbo_ttipcs021600.t_cprj = dbo_ttdsls041600.t_cprj)) LEFT JOIN dbo_ttiitm001600 ON dbo_ttdsls041600.t_item = dbo_ttiitm001600.t_item) ON dbo_ttdsls040600.t_orno = dbo_ttdsls041600.t_orno "
strsql = strsql & "WHERE (((dbo_ttdsls041600.t_orno)=" & Me.txtSalesOrderNo.Value & ") AND ((dbo_ttdsls041600.t_pono)>0)) "
strsql = strsql & "ORDER BY dbo_ttdsls041600.t_pono;"
The problem is on the
IIF(dbo_ttipcs021600.t_dsca is null,dbo_ttiitm001600.t_dsca,dbo_ttipcs021600.t_dsca) AS t_dsca
I used ISNULL() function, and it has the same result as using Is Null
3/28/2017 Update:
Those tables are linked tables from the SQL Server. I created local tables based on a subset data of those linked ones, and there's no missing data at all.

Very odd. But I've never had to work much with SQLServer tables. To use RunSQL and not get warnings, turn them off and on.
DoCmd.SetWarnings False
DoCmd.RunSQL ...
DoCmd.SetWarnings True

I'm just curious about this problem, so I did a different approach by using multiple layer of queries.
strsql = strsql & "INSERT INTO tempLineItems (OrderNo, PositionNo, PartNo, Description, PlannedDeliveryDate, Qty, Unit, Price, Curr, txta, LineItemText, Discount, Tax) "
strsql = strsql & "SELECT SO1.t_orno, SO1.t_pono, SO1.t_item, nz(SO1.t_dsca, dbo_ttiitm001600.t_dsca) AS t_dsca, SO1.t_ddta, SO1.t_oqua, SO1.t_cups, SO1.t_pric, SO1.t_ccur, SO1.t_txta, Null AS LineItemText, SO1.t_disc_1, SO1.t_cvat "
strsql = strsql & "FROM (SELECT SO.t_orno, SO.t_ccur, SO.t_pono, SO.t_item, SO.t_oqua, SO.t_pric, SO.t_cups, SO.t_ddta, SO.t_txta, SO.t_disc_1, SO.t_cvat, dbo_ttipcs021600.t_dsca "
strsql = strsql & "FROM (SELECT dbo_ttdsls040600.t_orno, dbo_ttdsls040600.t_ccur, dbo_ttdsls041600.t_pono, dbo_ttdsls041600.t_item, dbo_ttdsls041600.t_pric, dbo_ttdsls041600.t_cups, dbo_ttdsls041600.t_ddta, dbo_ttdsls041600.t_cprj, dbo_ttdsls041600.t_txta, dbo_ttdsls041600.t_disc_1, dbo_ttdsls041600.t_cvat, dbo_ttdsls041600.t_oqua "
strsql = strsql & "FROM dbo_ttdsls041600 INNER JOIN dbo_ttdsls040600 ON dbo_ttdsls041600.t_orno = dbo_ttdsls040600.t_orno "
strsql = strsql & "WHERE (((dbo_ttdsls040600.t_orno)=" & Me.txtSalesOrderNo & "))) SO "
strsql = strsql & "LEFT JOIN dbo_ttipcs021600 ON dbo_ttipcs021600.t_cprj = SO.t_cprj AND dbo_ttipcs021600.t_item = SO.t_item) AS SO1 LEFT JOIN dbo_ttiitm001600 ON dbo_ttiitm001600.t_item = SO1.t_item "
strsql = strsql & "ORDER BY SO1.t_pono;"
And this works!! I guess there's some issue in Access internally.

Related

Performing SQL queries taking inputs from Excel Table in VBA Macro

I would like to take inputs from a table in Excel to perform SQL query and output it to a location in the Excel sheet.
Macro:
Sub SQL(Dim strSQL as String)
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
strFile = ThisWorkbook.FullName
strCon = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strFile _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
cn.Open strCon
rs.Open strSQL, cn
Debug.Print rs.GetString
End Sub
SQL Query:
SELECT
e.`isin`,
b.*
FROM
`risk_reference`.`basket_debt` AS b
JOIN `risk_reference`.`etp` AS e
ON IF(
e.`parentid_override` > 0,
e.`parentid_override`,
e.`parentid`
) = b.`parentid`
AND e.`isin` = ?
AND e.`date_out` IS NULL
WHERE b.`processing_date` IN
(SELECT
MAX(processing_date)
FROM
`risk_reference`.`basket_debt`)
GROUP BY e.`isin`, b.`pk_id`
The ? in the SQL query is where I need a list of items to go in based on a table in Excel.
Should i do SQL query item by item or can i do it in one shot? If so, how do i do it? If I do line by line, how do I get to output one location in the excel?
Need some advise.
Assuming your variant of sql supports it, use IN and loop through cells to buiold the list
strsql = "SELECT e.`isin`, b.* FROM `risk_reference`.`basket_debt` AS b JOIN "
strsql = strsql & "`risk_reference`.`etp` AS e ON IF( e.`parentid_override` > 0, "
strsql = strsql & "e.`parentid_override`, e.`parentid`) = b.`parentid`"
strsql = strsql & "AND e.`isin` IN ("
dim c as range
for each c in range("your range here")
strsql = strsql & "'" & c.text & "',"
next c
strsql = strsql & ") "
strsql = strsql & "AND e.`date_out` IS NULL WHERE b.`processing_date` IN "
strsql = strsql & "(SELECT MAX(processing_date) FROM `risk_reference`.`basket_debt`) "
strsql = strsql & "GROUP BY e.`isin`, b.`pk_id`"

Query Returns Multiple Rows Instead of the max

I have a table in Access with the relevant fields EFTRecID, EFTRecIDNum and CreatedBy. EFTRecIDNum is an auto number field, and EFTRecID concatenates the required format of "CE" & EFTRedIDNum. I am attempting to return the highest value in the EFTRecID field that was created by the current user. To do this I am trying to do a sub query that finds the Max(EFTRecIDNum) WHERE Created = my name. However instead of returning the max, it is returning all values with my name. I know I could use the format option to just format the EFTRecIDNum field, but I need to be able to search in the format CE456.
TL;DR: Query returns all records with my name, rather then max with my name.
Public Sub DownloadMyRecords()
Dim intI As Integer 'Used for looping in a variety of locations
strSQL = "SELECT EFTRecID FROM tblEFTRec WHERE (SELECT MAX(EFTRecIDNum) FROM tblEFTRec WHERE CreatedBy = '" & Application.UserName & "')"
Set cnn = New ADODB.Connection
With cnn
.Provider = "Microsoft.ACE.OLEDB.12.0;Data Source=" & dbLocation & "\" & dbName & ";Jet OLEDB:Database Password=" & DBPWord
.Open dbLocation & "\" & dbName
End With
Debug.Print strSQL
Set rst = New ADODB.Recordset
rst.CursorLocation = adUseServer
rst.Open Source:=strSQL, ActiveConnection:=cnn, _
CursorType:=adOpenForwardOnly, LockType:=adLockOptimistic, _
Options:=adCmdText
Debug.Print (rst.GetString)
rst.Close
cnn.Close
Set rst = Nothing
Set cnn = Nothing
End Sub
Try this SQL statement instead:
strSQL = "SELECT EFTRecID
FROM tblEFTRec
WHERE EFTRecIDNum = (SELECT MAX(EFTRecIDNum) FROM tblEFTRec WHERE CreatedBy = '" & Application.UserName & "')"
Try using:
"SELECT EFTRecID FROM tblEFTRec
WHERE EFTRecIDNum = (SELECT MAX(EFTRecIDNum) FROM tblEFTRec
WHERE CreatedBy = '" & Application.UserName & "')"
Is there a reason the following doesn't work?
"SELECT MAX(EFTRecID) FROM tblEFTRec
WHERE CreatedBy = '" & Application.UserName & "'"

SELECT Queries in Access VBA

I have an Access database consisting of two tables, Individuals & Pairs. Individuals consists two columns; 'Bird_ID' and 'Parents_Pair_number' and Pairs consists of three columns; 'Pair', 'Female_ID' and 'Male_ID'. 'Parents_Pair_number' and 'Pair' have a Many-to-one relationship. Via this relation one can check the parents of an individual.
But now I was thinking of making automatized family trees using a form. My plan was to make a field (Bird_ID_Field) in which you can find a certain individual and that other fields such as Father, Mother, Fathers father etc. etc. would auto-fill based on that entry.
I tried to auto-fill the Father_ID (Field) using the following VBA code:
Dim strSQL As String
Dim strBird_ID As String
If Bird_ID_Field <> "" Then
strBird_ID = Bird_ID_Field
strSQL = "SELECT Pairs.[Male_ID] " & _
"FROM Pairs " & _
"WHERE PAIR = (SELECT Individuals.[Parents_Pair_number] FROM Individuals WHERE Individuals.[Bird_ID]= '" & strBird_ID & "');"
DoCmd.OpenQuery strSQL
Father_ID = strSQL
End If
But after updating the Bird_ID_Field I get the following error: Microsoft Access can't find the object ''.
Do you have any idea what's wrong?
Thanks in forward!
Jeroen
You should use recordsets:
Dim rst As Recordset
Dim strSQL As String
If Nz(Bird_ID_Field,"") <> "" Then
strBird_ID = Nz(Bird_ID_Field, "")
strSQL = "SELECT Pairs.[Male_ID] " & _
"FROM Pairs " & _
"WHERE PAIR = (SELECT Individuals.[Parents_Pair_number] FROM Individuals WHERE Individuals.[Bird_ID]= '" & strBird_ID & "');"
Set rst = CurrentDb.OpenRecordset(strSQL)
If rst.RecordCount > 0 Then
Father_ID = rst![Male_ID]
End If
End If
rst.Close
Set rst = Nothing
And also I would recommend to use JOIN for tables joining instead of subquery.

update query with inner join access vba code

I am trying to update a table from another one via a inner join query access vba. The field's name to be updated will be taken in a form.
I wrote this query, but it gives me error.
Dim dbs As Database
Dim qdf As QueryDef
Set dbs = OpenDatabase("Dba_Savings.mdb")
dbs.Execute " UPDATE TblClient INNER JOIN TblImport ON TblClient.Account_Id = TblImport.Account_Id" _
& " SET TblClient." & Me.txtNewFieldName & " = TblImport." & Me.txtNewFieldName2 & ";"
dbs.Close
Can anyone help me please.
Dim S As String
S = "UPDATE TblClient INNER JOIN TblImport ON TblClient.Account_Id = TblImport.Account_Id" _
& " SET TblClient." & Me.txtNewFieldName & " = TblImport." & Me.txtNewFieldName2 & ";"
Debug.Print S
dbs.Execute S
UPDATE TblClient INNER JOIN TblImport ON TblClient.Account_Id = TblImport.Account_Id SET TblClient.S_B_Mar-14 = TblImport.S_B_Mar-14;
The SQL work perfectly and update the table, No error.
You are missing a space between these two:
ON TblClient.Account_Id = TblImport.Account_Id" _
& "SET TblClient.
When building SQL in VBA, always assign the SQL to a string variable, then Debug.Print this variable. In this case, the error would be obvious.
Also this part is unnecessary, since it's already in the INNER JOIN:
WHERE TblClient.Account_Id = TblImport.Account_Id
Edit
Instead of
dbs.Execute " UPDATE TblClient INNER JOIN TblImport ON TblClient.Account_Id = TblImport.Account_Id" _
& " SET TblClient." & Me.txtNewFieldName & " = TblImport." & Me.txtNewFieldName2 & ";"
you do:
Dim S As String
S = "UPDATE TblClient INNER JOIN TblImport ON TblClient.Account_Id = TblImport.Account_Id" _
& " SET TblClient." & Me.txtNewFieldName & " = TblImport." & Me.txtNewFieldName2 & ";"
Debug.Print S
dbs.Execute S
Ctrl+G opens the Immediate Window, this will show the output of Debug.Print. Please add this to your question.
Then, if it still gives an error, you can also create a new query, switch to SQL view, copy & paste the output, and try to run the query. You will probably get a better error message. Or at least highlight the problematic part.

query a query in VBA

Hi guys I dont know if this makes sense but how can I query another query in VBA?
I will show with example below
This is my first query
strSQL1 = "SELECT DISTINCT SourceBank" _
& ", Fullname, FirstNames" _
& ", Surname, Company" _
& ", EmailAddress" _
& " FROM question" _
& " WHERE FirstNames = '" & strFirstNames & "'" _
Set rs = dbs.OpenRecordset(strSQL)
Then I want to do something like this. Query the first query
strSQL2 = "S"SELECT * from " & strSQL1
Set rs1 = dbs.OpenRecordset(strSQL)
I just want to know if this is possible and if not then what is the best way around it?
All I want to do is to be able to query another query/string/recordset.
thanks
You can do it almost like you've wrote:
strSQL2="SELECT * FROM (" & strSQL1 & ")"
but be sure not to include ; in strSQL1
upd, try:
strSQL2 = "SELECT Question.EmailAddress, SUBQUERY.EmailAddress &" _
& "FROM Question LEFT JOIN (" & strSQL1 & ") AS SUBQUERY ON Question.EmailAddress = SUBQUERY.EmailAddress"
OR just save sql1 into QueryDef (Query in ms access) and use it like source table.