I have to create excel macro which fetches from access database and update appropriate columns in excel worksheet.
I have never done VBA programming before, i am just able to write a code to connect to the database which is giving me error saying "Error in From clause".
Sub Button2_Click()
Dim conn As New Connection
Dim rs As New Recordset
strcon = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=C:\Users\Xprts8\Documents\shipping.accdb;" & _
"User Id=admin;Password="
conn.Open (strcon)
qry = "SELECT * FROM shipping-table"
rs.Open qry, conn, adOpenKeyset
rs.Close
conn.Close
End Sub
can anybody help me with the following problem
shipping-table is not a valid table name in an SQL statement (because of the hyphen) unless its escaped thusly:
SELECT * FROM [shipping-table]
Related
I have a number of Excel-Files that contain data which I need to combine into one table.
Is it possible and reasonable to do this from within Access VBA code, which I would prefer? Or should I just do it in Excel VBA?
My idea was to iterate through the Excel-Files and use an SQL statement for UPDATE Column WHERE MyCondition, to get the Values I want to the Column I want. Is it possible this way or what would be a suggestion to solving this?
I have tried it this way until now from Access:
Sub Execute_UpdateQuery()
Dim conn As ADODB.Connection
Dim NumOfRec As Integer
Dim strPath As String
strPath = "D:\Sortierliste August_September\Test.xlsx"
Set conn = New ADODB.Connection
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & strPath & ";Extended Properties=Excel 12.0 Xml;HDR=YES;"
conn.Execute "UPDATE Ware SET Name = 'test'" & _
" WHERE Name = 'Ackermann'", NumOfRec, adExecuteNoRecords
Debug.Print NumOfRec & " records were updated."
conn.Close
Set conn = Nothing
End Sub
But that results into an error "Cannot find access-database module "Ware". I guess it is because it is just an excel-table and not a database? I thought it can find an excel-file containing the table called Ware and execute an sql query. Any help or suggestions would be great on how to solve this issue.
Greetz
New to programming, SQL and VBA. I frequently work with decent size data tables and thought it would be helpful to add SQL query execution capability to apply to an existing excel table. Research led me to ADODB connections and found a great base snippet to work from here: https://blog.learningtree.com/excel-as-a-database-how-to-query-economic-data-with-sql/
I seem to running into limits though on how many rows are accessible before the next line of code runs. In my SQL statement source I can return 65k rows, any more in defining the source table size, and I get an Object does not exist error. Can you run ADODB recordset.Open asynchronously to ensure complete return of the object? - Any help would be very much appreciated.
Thanks!
tried to insert a WAIT inline:
rs.Open strSQL, Application.Wait (Now + TimeValue("0:00:30")), cn
but still errors out. See code below
Sub ExcelTbl_SQL()
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
strSQL = "SELECT * FROM [Sheet1$A1:AI146103] WHERE GROUP = 'HIX'"
rs.Open strSQL, cn
Dim ws As Worksheet
Set ws = Application.Sheets.Add
ws.Range("A1").CopyFromRecordset rs
rs.Close
cn.Close
'Debug.Print rs.GetString
End Sub
These are the results I am getting:
Works: strSQL = "SELECT * FROM [Sheet1$A1:AI65000] WHERE GROUP = 'HIX'"
Error: strSQL = "SELECT * FROM [Sheet1$A1:AI65437] WHERE GROUP = 'HIX'"
Run-time error '-2147217865 (80040e37)': The Microsoft Access database
engine could not find the object 'Sheet1$A1:AI65437'.
I think this is because you are calling old version library through this part of connection string:
Provider=Microsoft.ACE.OLEDB.12.0
You should try
Provider=Microsoft.ACE.OLEDB.16.0
Upd: Answer was here Excel as database - query more than 65536 rows? interesting. You cannot mention rows, or you'll get error.
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 & "]"
The following code works perfectly fine on my computer. I cannot understand why it's not working on another persons computer. Can someone lead me towards ideas that may help trouble shoot this?
The error (with on error commented out) is that the array isn't being loaded with data. Get an error like "either bof or eof is true for the current record"
Also I can tell you if the on error GoTo NEXTT is left on.. it goes there and tries to erase the array and returns a wrong data type error. Makes me think the array is empty.
I checked Conn.State and I can confirm that the connection is open.
Function sbADO(ban_id, upc_id, div_id)
'Must add Activex data objects libaray 2.8
Dim sSQLSting As String
On Error GoTo nextt
Dim Conn As New ADODB.Connection
Dim mrs As New ADODB.Recordset
Dim DBPath As String, sconnect As String
DBPath = ThisWorkbook.FullName
'You can provide the full path of your external file as shown below
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DBPath _
& ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";"
Conn.Open sconnect
sSQLSting = "SELECT * From [data$] where BANNER_ID IN (" & ban_id & ") AND UPC_ID IN (" & upc_id & ") AND DIVISION_ID IN (" & div_id & ") " 'Your SQL Statemnt (Table Name= Sheet Name=[DataSheet$])
mrs.Open sSQLSting, Conn
'=>Load the Data into an array
ReturnArray = mrs.GetRows
''OR''
'=>Paste the data into a sheet
'Sheets("Sheet1").Range("A2").CopyFromRecordset mrs
'Close Recordset
mrs.Close
'Close Connection
Conn.Close
'
Exit Function
nextt:
Erase ReturnArray
'mrs.Close
Conn.Close
'MsgBox (ReturnArray(6, 2)) '(feild, row)
End Function
The problem is because
DBPath = ThisWorkbook.FullName <-- the workbook is set to read only.
Removing read only status fixes the issue.
It seems like you're using ADO to query data in the same workbook? That might be for the purposes of simplifying this problem for SO, but it would be easier and faster to get the array you need by referring to the range directly. But in this answer, I'll assume that you really do want to use ADO.
You're trying to use ADO to open the workbook, but you're not specifying the ConnectionString or Open methods with any read-only arguments. Try making these adjustments:
'Add Mode=Read
sconnect = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & DBPath & _
";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=1"";Mode=Read;"
'Add adLockReadOnly
mrs.Open sSQLSting, Conn, , adLockReadOnly
I have a filled ADO recordset in my VBA module. I also have a table in ACCESS that has exactly the same structure as the recordset.
Now I fill the table using a loop (which is fine) going through each dataset record.
What I am wondering: is there a way to insert an entire recordset into the access table? (and more importantly: would this be significantly faster)
Here's a basic example (run from excel in this case) which illustrates using a disconnected recordset to add records.
Sub Tester()
Dim con As ADODB.Connection, rs As ADODB.Recordset
Dim i As Long
Set con = getConn()
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient '<<<< important!
'get an empty recordset to add new records to
rs.Open "select * from Table1 where false", con, _
adOpenDynamic, adLockBatchOptimistic
'disconnect the recordset and close the connection
Set rs.ActiveConnection = Nothing
con.Close
Set con = Nothing
'add some new records to our test recordset
For i = 1 To 100
rs.AddNew
rs("UserName") = "Newuser_" & i
Next i
'reconnect to update
Set con = getConn()
Set rs.ActiveConnection = con
rs.UpdateBatch '<<< transfer to DB happens here: no loop!
rs.Close
'requery to demonstrate insert was successful
rs.Open "select * from Table1", con, _
adOpenDynamic, adLockBatchOptimistic
Do While Not rs.EOF
Debug.Print rs("ID").Value, rs("UserName").Value
rs.MoveNext
Loop
rs.Close
con.Close
End Sub
Function getConn() As ADODB.Connection
Dim rv As New ADODB.Connection
Dim strConn As String
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" _
& "Data Source = " & ThisWorkbook.Path & "\Test.accdb"
rv.Open strConn
Set getConn = rv
End Function
VBA Recordsets exist virtually in memory called during runtime until they are contained into an actual physical format (i.e., csv, txt, xlsx, xml, database temp table) saved to hard disk. This is akin to data frames in R or Python pandas, SAS datasets, PHP arrays, and other data structures.
Consider exporting your ADO in such a format using CopyFromRecordset methods into an Excel spreadsheet to be saved as csv, txt, xlsx, or xml. Alternatively, you can use the Save method to save recordset in a persistent format type like xml.
Then, append resultant file to MS Access table with its automated data migration features:
For spreadsheets: DoCmd.TransferSpreadsheet
For txt, csv, or other delimited files: DoCmd.TransferText
For xml files: Application.ImportXML
For local or ODBC/OLEDB linked database tables: INSERT INTO append SQL query
To accomplish this with a SQL statement you use the SELECT/INSERT... IN [Designate DB A; record posted to] or FROM... IN [Designate DB B; record original source]
You can only use the IN statement once in a single query. Therefore you create the other connection using the ADODB connection to determine the other source connection.
Function example()
Dim dB_External As String
Dim db_Local As String
Dim cnLocal As ADODB.Connection
Dim cnExternal As ADODB.Connection
Set cnLocal = CurrentProject.Connection
Set cnExternal = New ADODB.Connection
cnExternal .Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\Users\\...accdb;Persist Security Info=False;"
dB_External = "C:\Users\\...accdb"
db_LOCAL = "C:\Users\\...accdb"
Example A:
strSQL = "INSERT INTO *Local table to receive records* (Column Designations)"
strSQL = strSQL & " SELECT ( *Corresponding records from external table* )"
strSQL = strSQL & " FROM *External table name* IN '" & dB_External & "'"
cnLocal.Execute (strSQL)
I use the above code, with the local ADODB connections if I select from a single external table.
Example B:
strSQL = "INSERT INTO *Local table to receive records* (Column Designations) IN '" & dblocal & "'"
strSQL = strSQL & " ( *Corresponding records from external table* )"
strSQL = strSQL & " FROM *External table name*
cnExternal.Execute (strSQL)
I use the above code using the external ADODB connection, if I select involves joining multiple tables in the external db.
No. There is no reverse equivalent - could be SetRows - to the method GetRows.