Copy and add a sheet to a closed workbook - sql

Using SQL I can access and edit cells in Excel workbooks without opening them in a vba script. However I have not yet found a way to copy or add a sheet in a similar way. Atm I use Workbook.Open and Copy to accomplish it. Is this possible?

I got the same problem and searched for hours until found this one using ADODB-Connection Object:
path= <yourFilePath>
set cn = new ADODB.connection
'create connection String
connStr="Provider=Microsoft.ACE.OLEDB.12.0; & _
"Data Source=" & path & ";" & _
"Extended Properties='Excel 12.0;HDR=YES;"";ReadOnly=0'"
cn.Open connStr
set cmd = new adodb.command
cmd.ActiveConnection = cn
'create sql-string
cmd.CommandText = "CREATE TABLE [<TableName>] (<anyString> char(255))"
cmd.Execute
see: VBA to add new sheet in a closed excel without opening & get the sheet name added?
I think that's what you and everyone else who stumble about this post is looking for.
Further you can create a String INSERT INTO [<TableName>$] VALUES('<values>') to add some data to the sheet.

Related

VBA Schema Table Doesnt Include Newly Added Worksheet

I have a VBA Code that connects to the workbook itself to execute SQL queries. The macro adds Worksheets during runtime.
E.g. ThisWorkbook.Sheets.Add.Name = "TempSheet"
After adding this worksheet, the VBA Macro adds data on the TempSheet.
I will be executing SQL query against the newly added worksheet using this code:
Dbase = ThisWorkbook.FullName
Connection_string = "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & Dbase & ";" & _
"Extended Properties=""Excel 12.0;HDR=YES"";"
Set cn = New ADODB.Connection
cn.Open Connection_string
SQL_String = "SELECT * FROM [TempSheet$A1:U182]"
Set rs = New ADODB.Recordset
rs.CursorLocation = adUseClient
rs.Open SQL_String, cn
On the line where it executes the query at rs.Open, I get an error saying
The Microsoft Access database engine could not find the object 'TempSheet$A1:U182'. Make sure the object exists and that you spell its name and the path name correctly. If 'TempSheet$A1:U182' is not a local object, check your network connection or contact the server administrator.
I am very sure that the Worksheet name matches but still it seems that VBA ADO cannot find the newly added worksheet on the workbook.
Appreciate your thoughts on this.

Trying to update Excel-Table through Access-VBA Code. Error: Cannot find database Object "Ware"

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

Can't insert records from Excel to SharePoint

Currently I am suffering Excel ADO issue.
Here is the thing taht
I was trying to insert some records
from "Excel table" to "SharePoint list" Using ADO connection.
But failed (Can't recognize Excel table in SQL Statement)
Dim SQL As String
Dim CN As New ADODB.Connection
Dim OLEDB As String
Dim LIST As String
Dim SITE As String
LIST = "{EE028282-3D7E-4D37-93EE-50FB69C4432C}"
SITE = "https://asml.sharepoint.com/teams/FFKR_DUV_YS_Installation_and_Relocation/Product"
OLEDB = "Provider=Microsoft.ACE.OLEDB.12.0;WSS;IMEX=0;RetrieveIds=Yes;" & _
"DATABASE=" & SITE & ";" & _
"LIST=" & LIST & ";"
Set CN = New ADODB.Connection
CN.Open OLEDB
SQL = SQL & "INSERT INTO Schedule_DB (NAME,TYPE_W) "
SQL = SQL & "SELECT * "
SQL = SQL & "FROM [" & ThisWorkbook.FullName & "].[S_RAW$] "
CN.Execute CommandText:=SQL
CN.Close
If I run it I got error ->
Error image
I have already check the miss-spell, and the amount of item is too much, so I would prefer to process it as a one SQL statement.
"Excel to Excel" works well But still have no ideas for "Excel to SharePoint List".
Please share your advice.
When you want to read data from your Excel sheet you need to have a ADODB.Connection with Read permission, then to write data to your SharePoint List you need to have another ADODB.Connection with Write permission.
Note: You can't transport your whole data in that way, You can generate a big command with whole data then use it or generate command for each record of your Excel data.
About your exception it is simply says it can't find your sheet name in SharePoint Lists.
A sample to guide you can be something like this:
Dim cnnXl As New ADODB.Connection
Dim rsXl As New ADODB.Recordset
Dim cnnShP As New ADODB.Connection
conStrXl = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source='C:\yourExcel.xlsx';" & _
"Extended Properties=""Excel 12.0;HDR=YES;IMEX=1;"";"
commandXl = "SELECT [Field1], [Field2] FROM [Worksheet$$A1:D7] WHERE [Thing1] > 1"
conStrShP = "Provider=Microsoft.ACE.OLEDB.12.0;WSS;IMEX=0;RetrieveIds=Yes;" & _
"DATABASE=yourSite;LIST={yourListCLSID};"
Then open cnnXl and run commandXl and read data to rsXl.
Then open cnnShP and loop over rsXl records and create your commandShP and execute it.

Excel vba - Convert dynamic range to static range then export to Access 2010 as new records

UPDATE 4
Posted solution.
UPDATE 3
Finally managed to find a solution to my problem, will post the answer shortly within the next few days.
UPDATE 2!
Put updates at the top for better readability.
So apparently it's not possible to use a named range from excel directly in the vba code when exporting to access.
After doing some more research I found there is a way around this: changing the dynamic range to a static range first and then using the entirety of the string as a variable.
However my current code down below says it cannot find the range even though I'm sure the syntax is correct, is this because I haven't set the reference to the excel file correctly?
Sub ExportAccess()
Dim cn As ADODB.Connection
Dim rs As ADODB.Recordset
Dim strQuery As String
myAddress = Replace(ThisWorkbook.Names("ExportData").RefersToRange.Address, "$", "")
myAddress = "[GWU$" & myAddress & "]"
' [Excel 8.0;HDR=NO;DATABASE=C:\Users\Public\test.xls] < unused code snippet
strQuery = "INSERT INTO Table1" & vbCrLf & _
"SELECT * FROM " & myAddress & ""
Set cn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "C:\Users\Public\Database.accdb"
.Open
End With
rs.Open strQuery, cn
cn.Close
rs.Close
Set rs = Nothing
Set cn = Nothing
End Sub
UPDATE!
After racking my brain for a few hours and checking the links I posted for some much needed reference, I came up with the following:
Sub ExportAccess()
Dim cn As ADODB.Connection
Dim strQuery As String
strQuery = "INSERT INTO Table1" & vbCrLf & _
"SELECT * FROM [Excel 8.0;HDR=YES;DATABASE=C:\Users\Public\test.xls].ExportData"
Set cn = New ADODB.Connection
With cn
.Provider = "Microsoft.ACE.OLEDB.12.0"
.ConnectionString = "C:\Users\Public\Database1.accdb"
.Open
.Execute strQuery
End With
With cn
.Close
End With
End Sub
I haven't been able to test this yet (will do this first thing tomorrow)
However I'm worried about the following code snippets:
"SELECT * FROM [Excel 8.0;HDR=YES;DATABASE=C:\Users\Public\test.xls].ExportData"
This should technically select the 'ExportData' range from the test worksheet based on a different question here on Stackoverflow, I'm just not 100% sure if it will work
.Open
.Execute strQuery
End With
With cn
.Close
End With
Will this actually perform the INSERT INTO? and is closing the the connection really required? (I'd assume so, just would like to know for sure)
Kind regards,
I've been trying to get what I have in my head working for a while now, but to be honest I don't have the required expertise right now. I'm still fairly new to programming so setting up my own variables and arrays that I can actually use is still very hard for me.
Hopefully you can help me out.
The situation:
So in an Excel read-only file I basically have a 10 row by 14 column range where users put their own data into, I want to only export the rows that have actual data that was filled in by these users to an Access 2010 database.
What I tried before: At first I wanted as simple of a solution as possible, I tried doing this by connecting the Excel worksheet to the Access database and then by doing a SQL append query on the rows where data is NOT NULL. (checks if entries in last column are NOT NULL)
However since many people will use the file at the same time I feared that the Access database/Connection to the Excel worksheet might get confused and start doing things it wasn't supposed to. When I tried to Google find out whether this was actually a problem or not my search results came up empty, so I was unsure if I should continue in this direction and ultimately abandoned this solution.
What I'm trying to do now: Basically I figured that I could do the same thing in an Excel macro before exporting, setting up a named range (via name manager) and then cutting out the rows that have no data in them with a simple macro before appending the remaining rows in the named range to the access database.
There are a few examples of people that have tried to do the same after a few google searches (unfortunately I can't post more than 2 links OR post linkbu.ch links):
Search results
However all of these examples seem to use a static range, not a dynamic range. How do I insert a Range from the name manager in VBA code? If anyone has any ideas on a different solution that would also be appreciated.
Kind regards,
FSDT
Use the macro recorder. Simply turn it on and manually go through the steps to export your named range. Then look at the VBA code you generated. The macro recorder is the greatest tool ever bestowed upon mankind. Try it, you'll like it.
All right everyone, as stated before this is the solution I came up with after trial and error:
Sub ExportAccess()
Dim cn As ADODB.Connection
Dim strQuery As String
Dim dbFilepath As String
Dim xlFilepath As String
dbFilepath = "C:\Users\Public\Database1.accdb"
xlFilepath = Application.ActiveWorkbook.FullName
xlFilepath = "[Excel 8.0;HDR=Yes;DATABASE=" & xlFilepath & ";IMEX=1]"
myAddress = Replace(ThisWorkbook.Names("ExportData").RefersToRange.Address, "$", "")
myAddress = "[Sheet1$" & myAddress & "]"
myAddress = "" & xlFilepath & "." & myAddress & ""
STRcn = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" & dbFilepath & ";"
strQuery = "INSERT INTO Table1" & vbCrLf & _
"SELECT * FROM " & myAddress & ""
Set cn = CreateObject("ADODB.Connection")
cn.Open STRcn
cn.Execute strQuery
cn.Close
Set cn = Nothing
End Sub

Import Excel sheet into datagridview - does workbook need to be closed to use OleDB?

I'm trying to import an Excel sheet into datagridview, but I'm getting hit with an error: "database or object is read-only." However, the workbook I'm referencing does not have the read-only attribute applied. That being said, the workbook I'm connecting to is already open if my application is running, so I suspect this is the reason I'm getting hit with this error. The workbook is open, thus appears to the system as read-only when trying to fill the dataset.
Am I right in this assumption? Is their a way to import an Excel sheet into datagridview using the OleDB connection if the workbook I'm connecting to is open? If not, is there any other way to populate this datagridview without having to do a massive loop through my sheet? My code is as follows:
Try
'connect to Excel data source and set gridview equal to dataset (entire sheet should be visible in gridview)
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
Dim connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & StatVar.workbookName & ";Extended Properties=""Excel 12.0;HDR=YES;Readonly=False"";" 'may need to use different MS provider and lower OLEDB for .xls files (Microsoft.Jet.OLEDB4.0...Excel 8.0) kind of sketchy though
MyConnection = New System.Data.OleDb.OleDbConnection(connstring) 'create a new data connection to Excel data source
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Budget$]", MyConnection) 'query the sheet - select all data
MyCommand.TableMappings.Add("Table", "Table") 'map data selection as table
StatVar.DtSet1 = New System.Data.DataSet 'create new data set
MyCommand.Fill(StatVar.DtSet1) 'fill data set with table
Form14.DataGridView1.DataSource = StatVar.DtSet1.Tables(0) 'populate gridview with data set table
MyConnection.Close()
Form14.ShowDialog()
Catch exc As Exception
MessageBox.Show("There was a problem loading this database. Please contact an administrator if the problem continues." & vbNewLine & vbNewLine & "Error: " & exc.Message)
End Try
I'm getting hit with the error here:
MyCommand.Fill(StatVar.DtSet1)
Did you try changing the connstring; set ReadOnly=True
If that doesn't work, you can make a copy of the workbook and then query that copy. If you do that it gets you the workbook as it was last saved. If that is a problem, you can do a save on the open workbook before copying.
Or better, simply ask the user to close the workbook before running the code.
Try
Cursor = Cursors.WaitCursor
'can't populate gridview with an open file using OLEDB - need to export the Budget sheet to a new file, close it, connect with OLEDB, then delete the temp Budget.xls file just created
'copy Budget sheet to new workbook, delete unneeded columns, save file as Budget.xls, close workbook
Dim filenm = "W:\TOM\ERIC\Budget Temp\Budget.xls"
StatVar.xlApp.Sheets("Budget").Copy()
StatVar.xlApp.ActiveWorkbook.Sheets("Budget").Columns("C:DY").Delete()
StatVar.xlApp.ActiveWorkbook.SaveAs("W:\TOM\ERIC\Budget Temp\Budget.xls")
StatVar.xlApp.ActiveWorkbook.Close(True)
'connect to Excel data source and set gridview equal to dataset (entire sheet should be visible in gridview)
Dim MyConnection As System.Data.OleDb.OleDbConnection
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
Dim connstring As String = "Provider=Microsoft.ACE.OLEDB.12.0;" & "Data Source=" & filenm & ";Extended Properties=""Excel 12.0;HDR=YES;Readonly=False"";" 'may need to use different MS provider and lower OLEDB for .xls files (Microsoft.Jet.OLEDB4.0...Excel 8.0) kind of sketchy though
MyConnection = New System.Data.OleDb.OleDbConnection(connstring) 'create a new data connection to Excel data source
MyCommand = New System.Data.OleDb.OleDbDataAdapter("select * from [Budget$A:F]", MyConnection) 'query the sheet - select all data in columns A:F
MyCommand.TableMappings.Add("Table", "Table") 'map data selection as table
StatVar.DtSet1 = New System.Data.DataSet 'create new data set
MyCommand.Fill(StatVar.DtSet1) 'fill data set with table
Form14.DataGridView1.DataSource = StatVar.DtSet1.Tables(0) 'populate gridview with data set table
MyConnection.Close()
'delete temporary Budget.xls file created at beginning of procedure and show Budget Codes form
File.Delete(filenm)
Form14.TxtBoxAutoCode.Text = StatVar.xlApp.Sheets("Budget").Range("EU2").Text
Form14.ShowDialog()
Catch exc As Exception
MessageBox.Show("There was a problem loading this database. Please contact an administrator if the problem continues." & vbNewLine & vbNewLine & "Error: " & exc.Message)
Finally
Cursor = Cursors.Default
End Try