Syntax error in FROM clause Excel VBA - vba

Here is my code to retrieve data from access but I always encounter "Run-time error '-2147217900 (80040e14)' Syntax error in FROM clause"
Sub UPDATE_REGION()
Dim cnn As New ADODB.Connection
Dim rst As New ADODB.Recordset
Dim AW As Workbook
Set AW = ActiveWorkbook
Path = AW.Path
cnn_pth = Path & "\Master File.accdb"
Set cnn = New ADODB.Connection
With cnn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open cnn_pth
End With
Set rst = New ADODB.Recordset
sSQL = "select Package_Nb from [package_db] where [Hubs] is null"
rst.Open Source:=sSQL, ActiveConnection:=cnn, CursorType:=adOpenForwardOnly, LockType:=adLockOptimistic, Options:=adCmdTable
end subs
When i stop script to debug, I found Source value in Local Window like this: "select * from select Package_Nb from package_db where Hubs is null"
I don't know why vba auto add select * from to source like this, anyone know how to fix this?

Your options are wrong. This:
Options:=adCmdTable
should be this:
Options:=adCmdText
Since you are not passing a table name but a SQL string. (when you pass a table name it is effectively converted into a SELECT * FROM table_name statement).

Related

DAO passthrough query using VBA: "Error 3131 Syntax error in from clause"

I copied a solution found in Stack Overflow, adapted it to my needs.
Public Function getAssortmentTypes(Optional personId As Variant) As DAO.Recordset 'personId is integer
Dim strQuery As String
Dim qdf As DAO.QueryDef
Dim rst As DAO.Recordset
If IsMissing(personId) Then
strQuery = "SELECT assortment_type.type_id, assortment_type.type_name AS qryTest FROM assortment_type"
Else
strQuery = "SELECT * FROM get_non_deleted_assortment_types_by_user(" & personId & ")"
End If
Set qdf = CurrentDb.CreateQueryDef("")
With qdf
.SQL = strQuery
.Connect = getDBConnectionString
.ReturnsRecords = True
End With
Set rst = qdf.OpenRecordset
Debug.Print rst!qryTest
Set getAssortmentTypes = rst
End Function
In my postgresql db I do have a working function and appropriate tables. I've tested sql queries with DBEaver and they work.
I'm receiving just one row (should be about 30) when I call the function without a parameter.
With a parameter I expect filtered resultset but receive
"Error 3131 Syntax error in from clause".
Always set the connection string before setting the SQL.
When you set the SQL, DAO doesn't have a clue this will later become a passthrough query, so it tries to parse it as Access SQL, and obviously fails, since it's not valid Access SQL.
Simply change the order:
With qdf
.Connect = getDBConnectionString
.ReturnsRecords = True
.SQL = strQuery
End With
Do note that you should be using parameters, and generally, use ADO instead of DAO when working with external data sources. DAO is great with Access, but offers less features with external data sources. ADO won't try parsing the SQL string before it actually needs to, for example.
Forgo the need for DAO and QueryDefs and use ADO with command parameterization which can then be binded to a recordset:
' SET REFERENCE TO Microsoft ActiveX Data Object #.# Library
Public Function getAssortmentTypes(Optional personId As Variant) As ADODB.Recordset
Dim conn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim cmd As ADODB.Command
Set conn As New ADODB.Connection
conn.Open getDBConnectionString
' PREPARED STATEMENT WITH QMARKS ?
If IsMissing(personId) Then
strQuery = "SELECT assortment_type.type_id, assortment_type.type_name AS qryTest FROM assortment_type"
Else
strQuery = "SELECT * FROM get_non_deleted_assortment_types_by_user(?)"
End If
Set cmd = New ADODB.Command
With cmd
.ActiveConnection = conn
.CommandText = strQuery
.CommandType = adCmdText
' BIND PARAMETER
.Parameters.Append .CreateParameter("user_param", adInteger, adParamInput, , personId)
' EXECUTE QUERY AND BIND INTO RECORDSET
Set rst = .Execute
End With
Set cmd = Nothing
Set getAssortmentTypes = rst
End Function
I don't recommend the introduction of ADO.
The issue looks to be that your first SQL query would (and does) work as a linked table, and thus works because it not a pass-through query.
The 2nd sql fails, since it still try to use "access" sql, and not postgresSQL syntax.
I recommend that you create a PT query (using Access UI). In the designer, make sure you select pass-though:
So, like linked tables - put the connection string in that PT query.
Do not put or attempt to place connection strings in the code. Your re-link routines can thus also include to re-link PT queries.
You can now use this code:
Public Function getAssortmentTypes(Optional personId As Variant) As DAO.Recordset 'personId is integer
Dim rst As DAO.Recordset
Dim strQuery As String
If IsMissing(personId) Then
strQuery = "SELECT assortment_type.type_id, assortment_type.type_name AS qryTest FROM assortment_type"
Else
strQuery = "SELECT * FROM get_non_deleted_assortment_types_by_user(" & personId & ")"
End If
With CurrentDb.QueryDefs("qryPT")
.SQL = strQuery
Set rst = .OpenRecordset
End With
Debug.Print rst!qryTest
Set getAssortmentTypes = rst
End Function
So, create a PT query called (for this example) qryPT
Try omitting the “DAO.” Prefix in your Recordset and dimension statements. Later versions of Access understand what you want.

Automation Error when Attempting to Query Access Database Using VBA

I've made the following ADODB object declarations in code.
Dim OConn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim fld As ADODB.Field
Set OConn = New ADODB.Connection
Set rs = New ADODB.Recordset
I would like to use the following code to read from a table on a MS Access database file and generate a recordset, rs.
'Get the table name from the search results.
tableName = ThisWorkbook.Sheets("PLC Module Data").Cells(2, 9).Value
'Set the SQL string.
strSql = "SELECT Code, Points, Type, Description, Rating " & _
"FROM " & tableName
'Set the connection string and open the connection to the Access DB.
OConn.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=Q:\AutoCAD Improvements\PLC IO Utility Docs\PLC IO Spreadsheet
App\PLC IO App\ace_plc.mdb"
OConn.Open
'Open the recordset and error out if nothing is returned
Set rs = OConn.Execute(strSql)
If rs.EOF Then
MsgBox "No matching records found."
rs.Close
OConn.Close
Exit Sub
End If
I've checked the query statement within the Access file itself and it works fine. I always get the error
Run-time error'-2147217900 (80040e14)': Automation Error
on the line,
Set rs = OConn.Execute(strSql)
If anyone could take a look over my code and determine why this is happening it would be much appreciated. I've looked at similar examples online and it seems like this should be correct.
I added the brackets around the tableName string and it works now. Thanks for all the feedback.
'Set the SQL string.
strSql = "SELECT Code, Points, Type, Description, Rating " & _
"FROM [" & tableName & "]"

VBA(AUTOCAD) SQL query to store String Values

I have a small issue, I am trying to code a Macro for Autocad in VBA.
I am trying to read a certain column value through sending a SQL native query that connects to the database server.
The problem is that my String variable descToReturn that's going to hold a value of that column is returning null. I can't seem to figure out where I am wrong. So if anyone can advise that'd be great.
Here's the code below:
Private Sub btnDuplicate_Click()
Dim cnn As ADODB.Connection
Dim rst As ADODB.Recordset
Dim ConnectionString As String
Dim StrQuery As String
Dim BOMLineToCheck As AcadBlockReference
Dim BOMAttributes As Variant
Dim partNoToCheck As String
Dim i As Integer
Dim descToReturn As String
ConnectionString = "Provider=SQLxxxxx.1;Password=xxxx;Persist Security Info=True;User ID=xxxx;Data Source=xx\xx;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Use Encryption for Data=False;Tag with column collation when possible=False;Initial Catalog=xxx_xxx"
Set cnn = New ADODB.Connection
cnn.ConnectionString = ConnectionString
cnn.Open
'cnn.CommandTimeout = 900
Set rst = New ADODB.Recordset
StrQuery = "SELECT * FROM [My Table Name] WHERE [My Column]='partNoToCheck'"
For Each BOMLineToCheck In ThisDrawing.ModelSpace
If BOMLineToCheck.Name = "BOM3LINE_old" Then
BOMAttributes = BOMLineToCheck.GetAttributes()
For i = 0 To UBound(BOMAttributes)
If BOMAttributes(i).TagString = "PART#" Then
partNoToCheck = BOMAttributes(i).TextString
End If
Next i
End If
rst.Open StrQuery, cnn, adOpenDynamic
With rst
If Not .EOF Then
descToReturn = rst![My Coulmn]
End If
End With
rst.Close
MsgBox descToReturn
Next
End Sub
Look closely for a typo:
descToReturn = rst![My Coulmn]
You probably mean:
descToReturn = rst![My Column]
See the difference?
So, I found the answer, because I am bringing SQL within VBA environment, the syntax was not right and its a weird syntax:
correct Syntax for SQL query:
StrQuery = "SELECT * FROM [My Table] WHERE [My Column]= '" & partNoToCheck & "'"

SQL Excel VBA Run-time Error 3709 Invalid Connection

This is my first question so constructive criticism is welcome! I am attempting to query an access database from excel vba and place the return information into an Excel range. I get this error:
Error Message: "Run-time error '3709' The connection cannot be used to
perform this operation. It is either closed or invalid in this
context."
Code:
Sub Importfromaccess()
Path = "C:\Users\myUser\Desktop\Database1.accdb"
Set cn = CreateObject("ADODB.connection")
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Path & ";"
Set rs1 = CreateObject("ADODB.recordset")
rs1.activeconnection = cn
Dim strSQL As New ADODB.Command
strSQL.CommandText = "SELECT * FROM Tooling WHERE TID=BD0001"
strSQL.CommandType = adCmdText
Set rs1 = strSQL.Execute ' This is the line the error occurs on
Sheets("Calc").Range("K1").CopyFromRecordset rs1
End Sub
I have enabled the following references:
Visual Basic For Applications,
Microsoft Excel 16.0 Object Library,
OLE Automation,
Microsoft Office 16.0 Object Library,
Microsoft Access 16.0 Object Library,
Microsoft ActiveX Data Objects 2.0 Library,
I tried placing the line:
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Path & ";"
right before the error line and received this error:
Run-time error '3705': Operation is not allowed when the object is
open.
Anybody know what my problem might be?
First (and unrelated to your error), unless you need to support clients using Windows 2000 or earlier, you should reference the highest Microsoft ActiveX Data Objects version instead of 2.0. If you're only using ADODB to interact with the database, you don't need the Microsoft Access 16.0 Object Library at all.
Second, if you already have a reference, don't create late bound objects like this:
Set cn = CreateObject("ADODB.connection")
Adding the reference early binds the type, so explicitly declare them and instantiate them using New:
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
Your connection string should be fine - where you run into problems are these 2 lines:
Set rs1 = CreateObject("ADODB.recordset")
rs1.activeconnection = cn
Executing an ADODB.Command will return the Recordset, not the other way around. Remove those 2 lines entirely. Instead of attaching the connection to the Recordset, you need to use it when you're building your ADODB.Command:
Dim strSQL As New ADODB.Command
strSQL.ActiveConnection = cn '<---Insert this.
strSQL.CommandText = "SELECT * FROM Table1"
strSQL.CommandType = adCmdText
Also, get rid of the Hungarian notation there - it's confusing as hell. An ADODB command isn't a String, so why should it be named strFoo?
You also need to clean up after yourself - don't leave your recordset and connection just hanging open when you're done with them. Call .Close when you're finished.
Finally, your SQL statement is most likely incorrect - you probably need to enclose your TID in single quotes('):
"SELECT * FROM Tooling WHERE TID='BD0001'"
It should look closer to this:
Sub Importfromaccess()
Dim Path As String
Path = "C:\Users\myUser\Desktop\Database1.accdb"
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Path & ";"
Dim query As New ADODB.Command
query.ActiveConnection = cn
query.CommandText = "SELECT * FROM Tooling WHERE TID='BD0001'"
query.CommandType = adCmdText
Dim rs1 As ADODB.Recordset
Set rs1 = query.Execute ' This is the line the error occurs on
Sheets("Calc").Range("K1").CopyFromRecordset rs1
'CLEAN UP AFTER YOURSELF:
rs1.Close
cn.Close
End Sub
You already Set rs1
How about trying something more like:
Sub Importfromaccess()
Dim strSQL As String, strPath as String
Dim cn as Object, rs1 as Object
strPath = "C:\Users\myUser\Desktop\Database1.accdb"
Set cn = CreateObject("ADODB.connection")
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & Path & ";"
Set rs1 = CreateObject("ADODB.Recordset")
strSQL = "SELECT * FROM Tooling WHERE TID='BD0001'"
rs1.Open strSQL, cn
Sheets("Calc").Range("K1").CopyFromRecordset rs1
End Sub
After some thorough rearranging I think I figured it out. I'm surprised at what changes fixed the problem but the following code works:
Dim con As New ADODB.Connection
Dim rs As ADODB.Recordset
Dim cmd As New ADODB.Command
cmd.CommandText = "SELECT * FROM Tooling WHERE TID='BD0001'"
con.Open "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=C:\Users\myUser\Desktop\Database1.accdb;"
cmd.ActiveConnection = con
Set rs = cmd.Execute
Sheets("Calc").Range("K1").CopyFromRecordset rs
rs.Close
con.Close
The final error was fixed with:
cmd.CommandText = "SELECT * FROM Tooling WHERE TID='BD0001'"
this line previously did not include single quotes around BD0001.
I also added an ActiveConnection to the Command object.
Edit: This is the simplest working version of this I could manage courtesy of all you helpful people!

VBA/SQL openrecordset(strSQL) Error 3001

I am trying to run a query on a database server (Oracle 10g) using VBA/Excel and to display the results in a excel table. I have created the ODBC connection (read-only) and tested the connection. I works fine if I import data as a data source in excel (I am able to filter through a query as well) However my VBA code is giving me Error 3001
Sub Test()
Dim cnn As ADODB.Connection
Dim canConnect As Boolean
Dim rs As Recordset
Dim strSQL As String
Set cnn = New ADODB.Connection
cnn.Open "DSN=blah;Uid=blah;Pwd=blah"
strSQL = "select job_start_dttm, job_end_dttm from c_job"
Set rs = cnn.openrecordset(strSQL)
ActiveCell = rs(0)
End Sub
I get Error 3001 - Arguemnts are of worng type, are out of acceptable range, or are in confilct with one another
The query itself runs fine in SQL developer. Thanks
edit: The error is on "Set rs = cnn.openrecordset(strSQL)" line
Try:
Sub Test()
Dim cnn As New ADODB.Connection
Dim canConnect As Boolean
Dim rs As New ADODB.Recordset
Dim strSQL As String
cnn.Open "DSN=blah;Uid=blah;Pwd=blah"
strSQL = "select job_start_dttm, job_end_dttm from c_job"
rs.Open strSQL, cnn
ActiveCell = rs(0)
End Sub
You seem to be mixing up a little DAO with your ADODB. You could have used Execute, but the above should suit.
Try qualifying the type name of rs with the ADODB prefix to make sure it is not being defined as the built-in Access Recordset object type instead.
Dim rs As ADODB.Recordset
Edit:
You will also need to use the ADO .Execute command instead of the DAO .OpenRecordset:
Set rs = cnn.Execute("...")