ACE Connection String From Excel 2010 to Itself - sql

I am trying to use SQL in VBA to update data in an existing table in Excel (same file as vba code). This is being written with SQL queries and updating with the intent of moving the source data to a DB shortly after rollout, but there are reasons why not right now. I keep getting the error "Operation must use an updateable query." Some sources show ReadOnly in the Extended Properties and some do not; both have been tried. StatusData is a named range in the Excel file. SELECT statements using the named range are working fine using the following connection string:
DBFullName = ThisWorkbook.Path & "\" & ThisWorkbook.Name
Cnct = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & DBFullName & "';" & _
"Extended Properties='Excel 12.0;HDR=Yes;IMEX=1';"
Changes from the query connection include using the "Excel 12.0 Macro" extended property and ReadOnly=0, which have been incrementally. Broken code is as follows:
Cnct = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & DBFullName & "';" & _
"Extended Properties='Excel 12.0 Macro;ReadOnly=0;HDR=Yes;IMEX=1';"
Set Cn = New ADODB.Connection
Cn.Open ConnectionString:=Cnct
strSQL = "UPDATE StatusData SET Notes='ttt' WHERE [Program Category]='something' AND [Program Name]='something' AND [LN]='1' AND [SN]='101';"
Cn.Execute strSQL, RecordsAffected, adExecuteNoRecords

I had problems using IMEX so in the end I stopped using it for this purpose, this connection string has never given me problems for using ADO/ACE to connect back to the workbook (usually for a SQL GroupBy), but you might need to do some conditioning on the data before making the connection (I take the entire table into an array and loop though the fields making changes as needed, then dump back to the sheet), easy enough as its already in the same workbook of course:
Dim conn As Object
Dim sPath As String
sPath = "C:\offlinestorage\temp1.xlsx"
Set conn = CreateObject("ADODB.Connection")
With conn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = Format("Data Source=" & sPath & ";Extended Properties='Excel 12.0 XML;HDR=Yes';")
.Open
End With

Related

Excel, VBA, SQL - Retrieve data from another workbook / Error

I want to retrieve data from a closed workbook.
My code is
fileName = "the path\test.xlsx"
With CreateObject("ADODB.Connection")
.CommandTimeout = 500
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& fileName & ";" & "Extended Properties=""Excel 12.0;HDR=YES;Readonly=true"";"
.Open
ThisWorkbooks.Worksheets("new").Range("A1").CopyFromRecordset .Execute("select * from [source$B1]")
.Close
End With
I have some error, 424:object required, object doesn't found... I think it is a syntax problem.
The purpose is to retrieve data from cells and put in the other sheet/workbook
thanks for your help
Three things:
Unless you defined "ThisWorkbooks" somewhere, I think it should be "ThisWorkbook".
Using this method, I have only ever been able to fetch ranges that contain ":" in them, so change source$B1 to source$B1:B1.
Since you only want one cell, you should turn the HDR (header) option off.
fileName = "the path\test.xlsx"
With CreateObject("ADODB.Connection")
.CommandTimeout = 500
.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" _
& fileName & ";" & "Extended Properties=""Excel 12.0;HDR=No;Readonly=true"";"
.Open
ThisWorkbook.Worksheets("new").Range("A1").CopyFromRecordset
.Execute("select * from [source$B1:B1]")
.Close
End With

Saving Results of Access Query To Worksheet Excel VBA

I cant seem to find an easy way of doing outside of just accessing the SQL from ACCESS SQL View and doing it manually. Is there some magic way to use this code below and do that?
Its worth pointing out that I am trying to do this from Excel's VBA.
Private Sub tryagain()
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
With con
.Provider = "Microsoft.ACE.OLEDB.12.0"
.Open "C:\Users\Ashleysaurus\Desktop" & "\" & "xyzmanu3.accdb"
End With
con.Execute "Invoice Query"
'How do output to Worksheet?
rs.Close
cmd.ActiveConnection.Close
End Sub
Simply use the ADO recordset object which you initialize, call the query, and then run the Range.CopyFromRecordset method (specifying the leftmost worksheet cell to place results).
Also, see the changed connection open routine with proper connection string. And because recordsets do not pull in column headers automatically but only data, an added loop was included iterating through recordset's field names.
Private Sub tryagain()
Dim con As New ADODB.Connection
Dim rs As New ADODB.Recordset
Dim strConnection As String
Dim i as Integer, fld As Object
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" _
& "Data Source='C:\Users\Ashleysaurus\Desktop\xyzmanu3.accdb';"
con.Open strConnection
rs.Open "SELECT * FROM [Invoice Query]", con
' column headers
i = 0
Sheets(1).Range("A1").Activate
For Each fld In rs.Fields
ActiveCell.Offset(0, i) = fld.Name
i = i + 1
Next fld
' data rows
Sheets(1).Range("A2").CopyFromRecordset rs
rs.Close
cn.Close
End Sub
By the way, this same above setup can even query Excel workbooks as the Jet/ACE SQL Engine is a Windows technology (.dll files) available to all Office or Windows programs.
strConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" _
& "Data Source='C:\Path\To\Workbook.xlsm';" _
& "Extended Properties=""Excel 8.0;HDR=YES;"";"
strSQL = "SELECT * FROM [Sheet1$]"

Pull and push data from and into sql databases using Excel VBA without pasting the data in Excel sheets

I want to use Excel vba to pull data from one database (server) and then push the same to another (local). However, I don't want to paste the data in any excel sheets during the process as this slows down the Excel a lot. How can I do this? Below is my work so far. I have highlighted where my code stops with error - Wrong number of arguments or invalid property assignment
Sub get_data_temp()
Dim cn As Object
Dim rs As Object
Dim strConnection As String
Dim server, port, id, pass As String
Dim strSQL As String
'get data from server (MS SQL based)
strSQL = Range("query_1").Value
server = Range("db_server").Value
port = Range("db_port").Value
id = Range("db_id").Value
pass = Range("db_pass").Value
Set cn = CreateObject("ADODB.Connection")
strConnection = "Provider=SQLOLEDB;Data Source=" & server & "," & port & ";User ID=" & id & ";Password=" & pass & ";"
cn.Open strConnection
Set rs = cn.Execute("SET NOCOUNT ON;" & strSQL)
'connect to ms access to import data
Dim xcn As Object
Dim xrs As Object
Dim xdbpath As String
Dim xstrConnection As String
Dim xdb_name As String
Dim xstrSQL As String
''''''''the code stops at the line below'''''''''''''
xstrSQL = "insert into crm_main select * from " & rs
''''''''the code stops at the line above'''''''''''''
xdb_name = "temp.accdb"
xdbpath = ThisWorkbook.Path & Application.PathSeparator & xdb_name
Set xcn = CreateObject("ADODB.Connection")
xstrConnection = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & dbpath
xcn.Open xstrConnection
xcn.Execute(xstrSQL)
cn.Close
Set cn = Nothing
xcn.Close
Set xcn = Nothing
End Sub

Update Data in Excel File From Different Excel File Using SQL

I have two Excel files, a master file and a regular file. Both files have a sheet with the same data structure (same fields, but not formatted as tables).
What I'm trying to do is use VBA to create data connections to both files, and then use SQL to update the master file with any changes in the regular file. The reason for using SQL and a data connection is to avoid opening the regular file and hopefully faster performance overall.
I'm having difficulty with the UPDATE statement, and I'm not sure I'm even going about this in the best manner. My code thus far:
Sub Main()
Dim cnn1 As New ADODB.Connection
Dim cnn2 As New ADODB.Connection
Dim rst1 As New ADODB.Recordset
Dim rst2 As New ADODB.Recordset
Dim arrData() As Variant
Dim fPath As String
With Application.FileDialog(msoFileDialogFilePicker)
.AllowMultiSelect = False
.Filters.Add "Files", "*.xls*"
.InitialFileName = ThisWorkbook.Path & "/Meeting Cuts"
.Title = "Please select the file that contains the values you'd like to import."
.Show
fPath = .SelectedItems(1)
End With
DoEvents
cnn1.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & CStr(fPath) & ";" & "Extended Properties=""Excel 12.0;HDR=Yes;"";"
cnn2.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & CStr(ThisWorkbook.FullName) & ";" & "Extended Properties=""Excel 12.0;HDR=Yes;"";"
rst1.Open "SELECT * FROM [Sheet1$];", cnn1, adOpenStatic, adLockReadOnly
rst2.Open "UPDATE [Account Data$]" & _
"SET Account_ID = (SELECT Account_ID FROM " & rst1.GetRows & " WHERE Empl_Name = 'Smith,John')" & _
"WHERE Empl_Name = 'Smith,John'", cnn2, adOpenStatic, adLockReadOnly
Set rst1 = Nothing
Set rst2 = Nothing
Set cnn1 = Nothing
Set cnn2 = Nothing
End Sub
When I execute the code, I get a Run-time error '13': Type Mismatch on the rst2.Open line. When I go into debug mode and try to execute that line again, I get a different error: Run-time error '3021': Either BOF or EOF is True, or the current record has been deleted. Requested operation requires a current record.
I know that I'm using GetRows improperly. Is there a way to reference the sheet (from the regular file) somehow in the UPDATE statement? If so, how would I do it?

Update Excel data via SQL UPDATE

I'd like to update my Excel sheet's data via an SQL query. I know you can 'connect' to a sheet via ADODB.Connection and retrieve (SELECT) data from it in a ADODB.Recordset. However using the same process for an UPDATE query produces an 'Operation must use an updateable query' error. Is there any other way to achieve this?
An example code that produces the error:
Sub SQLUpdateExample()
Dim con As ADODB.Connection
Dim rs As ADODB.Recordset
Set con = New ADODB.Connection
con.Open "Driver={Microsoft Excel Driver (*.xls)};" & _
"DriverId=790;" & _
"Dbq=" & ThisWorkbook.FullName & ";" & _
"DefaultDir=" & ThisWorkbook.FullName
Set rs = New ADODB.Recordset
Set rs = con.Execute("UPDATE [Sheet1$] SET a = 10 WHERE b > 2")
Set rs = Nothing
Set con = Nothing
End Sub
The code expects to be in a saved .xls worksheet where Sheet1 includes a table with column headers (at least) a and b.
Didn't think that would be all to make it work...
Answer
Connections to Excel files are set to ReadOnly as default.
You have to add ReadOnly=False to your Connection String.
More information can be found at Microsoft Support