I've found lots of posts on this problem, but so far no solutions have helped.
I'd like to read and write data from/to an Excel worksheet from an external VBA application - so far it reads OK, but I get an error while trying to write values to the ADODB Recordset.
Here's the code:
Sub UpdateFromExcel()
'https://stackoverflow.com/questions/15620080/reading-data-using-oledb-from-opened-excel-file
Dim oConn As New ADODB.Connection
Dim oRS As New ADODB.Recordset
Dim sPath
Dim sSQL As String
sSQL = "SELECT * FROM [Sheet1$A1:N10000]"
sPath = frmExcelSync.txtFilePath
oConn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & sPath & "';" & _
"Extended Properties='Excel 12.0;HDR=Yes;IMEX=1';"
oRS.Open sSQL, oConn, adOpenDynamic, adLockOptimistic
Do While Not oRS.EOF
'ITERATE THROUGH EACH ROW HERE
'ADD CODE ABOVE
'****GET AN ERROR HERE:****
oRS.Update "Occurrence Name", "Test"
oRS.MoveNext
Loop
oRS.Close
oConn.Close
End Sub
The error is
"Cannot update. Database or object is read-only".
I've tried different lock and cursor types, and I've tried editing the fields then using the .update method, but nothing has worked so far.
Any suggestions?
your update statement is not correct. I believe you want to update the column "Occurrence Name" with the value "Test"
What you should write is.
Do While Not oRS.EOF
oRS![Occurrence Name].value = "Test"
oRS.MoveNext
Loop
oRS.Update
The problem seems to have gone away somehow.
I tried a few different things (different spreadsheets) with mixed success then restarted the application - now it works.
No code changes at all.
Related
Set wb = xl.Workbooks.Open(fileName)
Set ws = wb.Sheets("Sheet1")
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & fileName & ";Extended Properties=""Excel 8.0;HDR=YES;IMEX=1;"";"
Set rs = db.OpenRecordset("Tracking", dbOpenTable)
ws.Cells.ClearFormats
The bug trigger according to access is
Set rs = db.OpenRecordset("Tracking", dbOpenTable)
as "Type mismatch". I have already build a table name as "Tracking" in my access application, so I was confused why it is not processed.
PS. I am trying to add new records from Excel to Access table through recordset.
Thanks in advance!
It seems that the problem does not have anything to do with Excel. In order to help somehow, there should be a way to make a MVCE, which would actually be enough for everyone to copy, paste it and replicate the error.
Something like this in Access is quite enough:
Sub TestMe()
Dim rs As Recordset
Dim db As Database: Set db = CurrentDb
Set rs = db.OpenRecordset("Tracking", dbOpenTable)
End Sub
If you still have problems with even this code, then it is a good start.
I'm putting together an Excel front-end with an Access database behind it, so that some of my colleagues can collate data from previous projects (without having to learn to use Access themselves!)
So I have a "Data" sheet in the Excel workbook that occasionally refreshes from the database, then a "Dashboard" sheet that allows filtering of that data.
Where I'm having trouble is in closing the loop - allowing input of new data into the database. The relevant code is below:
Private Sub btnDBImport_Click()
Dim rst As ADODB.Recordset
Dim errorList As String
Dim cn As ADODB.Connection
Set cn = New ADODB.Connection
With cn
.Provider = "Microsoft.ACE.OLEDB.16.0"
.ConnectionString = "\\FileAddress\DB.accdb"
.Open
End With
Set rst = New ADODB.Recordset
rst.CursorLocation = adUseServer
rst.Open Source:="TableName", _
ActiveConnection:=cn, _
CursorType:=adOpenDynamic, _
LockType:=adLockOptimistic, _
Options:=adCmdTableDirect
If validationTest = False Then
errorList = errorList & "Data at row " & i & " was not added to the database due to missing information." & vbCrLf
Else
rst.AddNew
With rst
.Fields(1) = Value1
.Fields(2) = Value2
End With
rst.Update
End If
Next i
If errorList <> "" Then
MsgBox errorList, vbOKOnly, "Data error"
End If
rst.Close
Set rst = Nothing
cn.Close
Set cn = Nothing
End Sub
The above is everything involved in defining, opening and working on a recordset; I get an error at rst.AddNew because "cannot update, database or object is ReadOnly".
Any help appreciated.
So, with thanks to the comment from Jimmy Smith, I've got to the bottom of this, or at least fixed my immediate problem.
The table was being treated as ReadOnly both when accessed through MS Access directly and when loaded as a Recordset using VBA because there was a link to the table in the same Excel workbook.
Now that I've deleted the link to the table and instead update the records in it through code, I'm consistently getting requested levels of access to the relevant table and everything is working as intended. Time to commit to Rubberduck and show it to the userbase.
I have an access file with over 3 milion records. I would would like that excel will be able to perfrom a vlookup serach in the access table and give me the result on excel. Any simple way to do that?
Thank's!
That would be a terribly inefficient way to do it.
In a database you can use queries with JOINs to do this. If you tell us, what the table looks like and what you want to achieve, we can give you more info.
As Andre451 said - you need SQL rather than Excel functions to get data out of the database.
This code will dump the query results into the immediate window. It should show you how to extract data from Access though.
Note - I usually make the oDB variable global if I'm planning on querying the database a lot. Also without knowing the name of your database or table structure I've just shown an example of the query used - you'll have to add code to get the employee number and year from the user.
Tip - Write your query in Access using the query editor, view it as SQL and then copy to Excel.
Sub ReturnValues()
Dim oDB As Object
Dim rst As Object
Set oDB = GetDatabaseReference
Set rst = CreateObject("ADODB.RecordSet")
With rst
.CursorType = 2
.Open "SELECT Salary FROM tbl_SomeTable WHERE Emp=1 AND Year=2015", oDB
If Not rst Is Nothing Then
If Not .BOF And Not .EOF Then
.MoveFirst
Do
Debug.Print rst.Fields("Salary")
.MoveNext
Loop While Not .EOF
End If
End If
End With
End Sub
Public Function GetDatabaseReference() As Object
Dim cn As Object
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'Only set a reference to the database if it doesn't already exist. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
If oDB Is Nothing Then
Set cn = CreateObject("ADODB.Connection")
Select Case Val(Application.Version)
Case 11
'Access 2003
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source =C:<Full Path To Database>.mdb;"
'Could use:
'"Data Source=" & ThisWorkbook.Path & "\Database\Database.mdb"
Case 14
'Access 2010
cn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source =C:<Full Path To Database>.mdb;" & _
"Persist Security Info=False;"
''Could use:
'"Data Source=" & ThisWorkbook.Path & "\Database\Database.mdb;" & _
'"Persist Security Info=False;"
End Select
If Not cn Is Nothing Then
Set GetDatabaseReference = cn
End If
Else
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
'oDB already has a reference, so ensure it's maintained. '
''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Set GetDatabaseReference = oDB
End If
End Function
I am new to vba and I am using vba script to connect to database from excel and get the records. I have written the following script for that.I am getting a run time error '-2147467259(80004005)':Unspecified error.
How to resolve this error. See the error screen shot.
Sub Ora_Connection()
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Dim query As String
Set con = New ADODB.Connection
Set rs = New ADODB.Recordset
'--- Replace below highlighted names with the corresponding values
strCon = "Driver={Microsoft ODBC for Oracle}; " & _
"CONNECTSTRING=(DESCRIPTION=" & _
"(ADDRESS=(PROTOCOL=TCP)" & _
"(HOST=host_name)(PORT=1521))" & _
"(CONNECT_DATA=(SERVICE_NAME=service_name))); uid=id; pwd=pw;"
'--- Open the above connection string.
con.Open (strCon)
'--- Now connection is open and you can use queries to execute them.
'--- It will be open till you close the connection
query = "select * from security.forms"
Set rs = con.Execute(query)
For i = 0 To rs.Fields.Count - 1
Sheet1.Cells(1, i + 1).Value = rs.Fields(i).Value
Next
con.Close
End Sub
Error screen shot:
Had you tried to use the open method of your RecordSet instance? Maybe it will give you another error that will be more helpful.
Dim connection As New ADODB.connection
Dim rst As New ADODB.Recordset
Dim query As String
connection.ConnectionString = CONNECTION_STRING
connection.Open
rst.Open query, connection, adOpenKeyset, adLockOptimistic
do while not rst.EOF
rst.MoveNext
loop
connection.Close
I had the exact same problem and it was tough to find an answer since most posts on this issue are unanswered.
I solved it by using another Oracle driver. Instead of Microsoft ODBC for Oracle try using the Oracle in OraClient11g_home1 driver. Hope this helps
Please add the reference 'Microsoft ActiveX Data Objects 2.8 Library'
What I'm trying to do is, while in Excel, use VBA to push data to an existing Access table. I've been able to do this, but am having one small hiccup. Before I push the data to access, I want to clear the current data on the Access table, so when the new data from Excel comes in, it is the only data in the Access table. I really don't know how to write code for Access since the class has been on VBA for Excel. I've tried several different approaches and each time it doesn't work. For example, the code that seemed like it should work is
DoCmd.RunSQL "DELETE tblName.* FROM CoversheetTableFourthAttempt
but I get an error telling me to define an object.
If you could help me with this, I would really appricate it
I've put my code below for reference.
Sub AccessFourthMonth()
Dim cn As ADODB.Connection, rs As ADODB.Recordset, r As Long
' connect to the Access database
Set cn = New ADODB.Connection
cn.Open "Provider=Microsoft.Jet.OLEDB.4.0; " & _
"Data Source=C:\Users\Kent\Documents\MBA\Winter 2009 Semester\MBA 614\Final Project\shilded\testdatabase.mdb"
' open a recordset
Set rs = New ADODB.Recordset
rs.Open "CoversheetTableFourthAttempt", cn, adOpenKeyset, adLockOptimistic, adCmdTable
' all records in a table
r = 2 ' the start row in the worksheet
Do While Len(Range("A" & r).Formula) > 0
' repeat until first empty cell in column A
With rs
.AddNew ' create a new record
' add values to each field in the record
.Fields("Project") = Range("A" & r).Value
.Fields("Description") = Range("B" & r).Value
.Fields("Amount") = Range("C" & r).Value
.Fields("Date") = Range("D" & r).Value
.Update ' stores the new record
End With
r = r + 1 ' next row
Loop
rs.Close
Set rs = Nothing
cn.Close
Set cn = Nothing
End Sub
Try
DoCmd.RunSQL "DELETE * FROM TableName"
This article might be of interest: Executing SQL Statements in VBA Code
Try the following from Excel:
dim cn as adodb.connection
dim cmd as adodb.command
set cn = new adodb.connection
cn.open "put your connection string here"
set cmd = new adodb.command
cmd.commandtype = adcmdtext
cmd.commandtext = "Delete * from myTable"
cmd.activeconnection = cn.connectionstring
cmd.execute
DoCmd is internal to Access application and not recognized by Excel application.
Simple approach to your problem is to fire the delete query from Excel itself.
Add this part after your cn.Open "Provider.. line
cn.Execute "DELETE * FROM CoversheetTableFourthAttempt"
This should clear the table before next part which fills the data runs.
Your DoCmd approach has two problems. You used a quote to start a string, but didn't include a closing quote. But even with proper quoting, your DoCmd won't work because Excel does not know that CoversheetTableFourthAttempt is the name of a table in an Access database.
You showed that you can successfully create an ADO connection to your Access database. So my suggestion is to use the Execute method of the connection object to execute your SQL statment:
cn.Execute "DELETE FROM CoversheetTableFourthAttempt;"
Finally, visit Problem names and reserved words in Access to understand why Date, Description, and Project are not great choices for Access field names.