I have an excel file 'test.xlsx' which contains a sheet called 'SheetName', which contains a named range called 'NamedRange'.
I want to write a script in visual basic to import these named ranges into an SQL database. So far I have tried openrowset, but I cannot find the correct syntax to reference a named range. An example of a query that doesn't work:
USE [Test_DataBase]
GO
SELECT * INTO New
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=D:\Test.xlsx', NamedRange);
GO
The error from this is: The OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" does not contain the table "NamedRange". The table either does not exist or the current user does not have permissions on that table.
I can however import the complete worksheet by using:
USE [Test_DataBase]
GO
SELECT * INTO New
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=D:\Test.xlsx', SheetName$);
GO
I have also tried:
USE [Test_DataBase]
GO
SELECT * INTO New
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=D:\Test.xlsx', SheetName$NamedRange);
GO
But that produces the following error: The OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" does not contain the table "SheetName$NamedRange". The table either does not exist or the current user does not have permissions on that table.
So, can openrowset actually be used to reference named ranges? If not is there an alternative method I could use instead?
*This is my first question, I hope I've been clear enough and haven't broken any rules!
Craig
You can use SSIS.
You can use Wizard "import data": Right click DB -> Tasks -> Import Data
First install the driver, from the link below.
https://www.microsoft.com/en-us/download/details.aspx?id=13255
sp_configure 'show advanced options', 1;
RECONFIGURE;
GO
sp_configure 'Ad Hoc Distributed Queries', 1;
RECONFIGURE;
GO
USE YourDatabase;
GO
SELECT * INTO Table1
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=C:\your_path\test.xlsx', [Sheet1$nr]);
GO
-- 'nr' is your named range
See these links for more details.
http://www.ashishblog.com/importexport-excel-xlsx-or-xls-file-into-sql-server/
https://www.red-gate.com/simple-talk/sql/t-sql-programming/questions-about-using-tsql-to-import-excel-data-you-were-too-shy-to-ask/#sixth
https://www.excel-sql-server.com/excel-sql-server-import-export-using-vba.htm
dbWb = ThisWorkbook.FullName
dsh = "SheetName$"
xlrow = Sheets("Sheet1").Cells(Rows.Count, "A").End(xlUp).Row
SELECT * FROM [Excel 12.0;HDR=YES;DATABASE=" & dbWb & "].[" & dsh & "A1:X" & xlrow & "] as aa"
Related
I am trying to automatically import tables from an excel sheet into a table in an SQL database via VB.net. So far I have done the following:
I created a stored procedure in the database which imports the table via openrowset:
CREATE PROCEDURE ImportTable
AS
SET NOCOUNT ON;
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
EXEC sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
SELECT *
INTO [Table]
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 12.0; Database=C:\ExcelFile.xlsm', Table$);
GO
Once created this procedure works perfectly when executed in SSMS.
I then wrote a script in VB.net to run the stored procedure with the same login details:
Dim ConnectionString As String
Dim sqlCon As SqlConnection
' Open a database connection and use it to run the stored procedure
ConnectionString = "Data Source=ServerName;" &
"Initial Catalog=DBName;" &
"User=UserName;" &
"Password=Password;" &
"Integrated Security=SSPI;"
sqlCon = New SqlConnection(ConnectionString)
Using (sqlCon)
Dim sqlComm As New SqlCommand
sqlComm.Connection = sqlCon
sqlComm.CommandText = "ImportTable"
sqlComm.CommandType = CommandType.StoredProcedure
sqlCon.Open()
sqlComm.ExecuteNonQuery()
End Using
However when I try to run the SP in VB.net (or VB excel) I get the following error:
System.Data.SqlClient.SqlException: 'Cannot initialize the data source object of OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "Unspecified error".'
I have looked around and found multiple threads on getting this to work in SSMS, but no solutions for a situation where it runs fine in SSMS but not in VB.net.
Any idea why the SP wont run through a method external to SSMS?
Craig
First Make sure the Excel file isn't open.
Then you need to check whether you have installed the 2007 Office System Driver: Data Connectivity Components which is necessary for Microsoft OLEDB ACE 12.0 driver to work.
or you can
USE [master]
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'AllowInProcess', 1
GO
EXEC master.dbo.sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0', N'DynamicParameters', 1
GO
Nice Link
I can't seem to find any good reference or example of how to get this to work. I have a database which is stored on an AS/400 (my local MS Access database [stored on a network drive] has linked tables to the 400, using ODBC/DSN). My utility works just fine passing SQL statements to through Access to retrieve data from the 400 using the linked tables. The problem is that with some of the larger reports and the fact that the 400 is several states away, it can take several hours to run the reports. The settled on solution to this is to create a local "copy" of the tables needed with just the data set that is relevant to the reports, which is a considerably smaller data set. Obviously this has the down side of not being "live" data but I can live with that. Ultimately what I want to do is gather the relevant data from the linked table and save it to separate database that is local to the client so that it could be used if offsite/offline and to increase the speed of the report.
network location stored database = DB1 (Tabled linked to AS/400)
local client stored database = DB2 (relevant data set created by below SQL, non-linked tables named the same as the linked tables)
Below is the SQL statement that I'm trying to get to work using VBA & DAO
SELECT
DB1_TABLEA.FIELD1,
DB1_TABLEA.FIELD2,
DB1_TABLEA.FIELD3,
DB1_TABLEA.FIELD4,
DB1_TABLEA.FIELD5,
DB1_TABLEA.FIELD6,
DB1_TABLEA.FIELD7,
DB1_TABLEA.FIELD8
INTO
DB1_TABLEA IN 'Local_DB_Copy.accdb' <== Creating non-linked copy
FROM
DB1_TABLEA
WHERE
(
((DB1_TABLEA.FIELD4) Like 99999)
AND
((DB1_TABLEA.FIELD6)="02" Or (DB1_TABLEA.FIELD6)="22")
)
;
I already have my program working fine and returning/processing data from the AS/400 DB. I just need to be able to get the above to work so that people have the option to run a local copy that will process much faster.
Below is the code that I tried, but of course it fails or I wouldn't be here.
Sub gCreateLocalDBTables()
Dim DBPath As String
Dim LocalDBPath As String
Dim sSQL As String
Dim DB As DAO.Database
Dim DB2 As DAO.Database
Dim RS As DAO.Recordset
LocalDBPath = "AS400_Local.accdb"
sSQL = "SELECT DB1_TABLEA.FIELD1, DB1_TABLEA.FIELD2, DB1_TABLEA.FIELD3, DB1_TABLEA.FIELD4, DB1_TABLEA.FIELD5, DB1_TABLEA.FIELD6, DB1_TABLEA.FIELD7, DB1_TABLEA.FIELD8 INTO DB2_TABLEA IN '" & LocalDBPath & "' FROM DB1_TABLEA WHERE (((DB1_TABLEA.FIELD4) Like 99999) AND ((DB1_TABLEA.FIELD6)='02' Or (DB1_TABLEA.FIELD6)='22'));"
Set DB = OpenDatabase(LocalDBPath, False, False)
DB.TableDefs.Delete ("DB2_TABLEA")
DB.Close
DBPath = Interaction.GetSetting("Cust_Tools", "Settings\Report_Planning", "400DB_Location")
Set DB2 = OpenDatabase(DBPath, False, False)
Set RS = DB2.OpenRecordset(sSQL)
RS.Close
DB2.Close
Set RS = Nothing
Set DB = Nothing
Set DB2 = Nothing
End Sub
I know the SQL works as I have tested it from inside MS Access. I just can't find info on how to get it to work being passed from Excel VBA
You cannot assign an action query like a make-table query (i.e., SELECT with INTO call) to a recordset. Consider executing your DROP and SELECT ... INTO action queries prior to opening recordset on the local table. Also, it is unclear why you are opening a second database or what the path points to. Below opens a recordset on the mainframe data:
Set DB = OpenDatabase(LocalDBPath, False, False)
DB.Execute "DROP TABLE DB2_TABLEA", dbFailOnError
DB.Execute sSQL, dbFailOnError
Set RS = DB.OpenRecordset("SELECT * FROM DB2_TABLEA")
Furthermore, the IN clause in your make-table query is unnecessary as you are currently connected to the very database you are running the action on. Simply remove it ('" & LocalDBPath & "'). Also, LIKE expressions without wildcards and on numbers should be replaced with =
SELECT
DB1_TABLEA.FIELD1,
DB1_TABLEA.FIELD2,
DB1_TABLEA.FIELD3,
DB1_TABLEA.FIELD4,
DB1_TABLEA.FIELD5,
DB1_TABLEA.FIELD6,
DB1_TABLEA.FIELD7,
DB1_TABLEA.FIELD8
INTO
DB2_TABLEA
FROM
DB1_TABLEA
WHERE
(
((DB1_TABLEA.FIELD4) = 99999)
AND
((DB1_TABLEA.FIELD6)='02' OR (DB1_TABLEA.FIELD6)='22')
)
;
In fact, consider saving the query inside the MS Access database (Ribbon -> Create -> Query Design -> SQL View) and call it as a named object and avoid any long SQL in VBA.
DB.Execute "DROP TABLE DB2_TABLEA", dbFailOnError
DB.Execute "mySavedQuery", dbFailOnError
Set RS = DB.OpenRecordset("SELECT * FROM DB2_TABLEA")
I have this table that I want to export its data into my excel file.
so far I've tried every topic here but nothing worked.
I've tried these 2:
insert into OPENROWSET('Microsoft.Jet.OLEDB.4.0',
'Excel 8.0;Database=D:\excel\testing.xls;',
'SELECT * FROM [newStart$]') select * from OutputResult
insert into OPENROWSET('Microsoft.ACE.OLEDB.12.0',
'Excel 8.0;Database=D:\excel\testing.xls;',
'SELECT * FROM [newStart$]') select * from OutputResult
when I run it with jet I'll get this error:
OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)" returned message "The Microsoft Jet database engine could not find the object 'newStart$'. Make sure the object exists and that you spell its name and the path name correctly.".
Msg 7350, Level 16, State 2, Line 1 Cannot get the column information from OLE DB provider "Microsoft.Jet.OLEDB.4.0" for linked server "(null)".
and when I ran the ACE.OLEDB I get this one:
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "The Microsoft Office Access database engine could not find the object 'newStart$'. Make sure the object exists and that you spell its name and the path name correctly.".
Msg 7350, Level 16, State 2, Line 1
Cannot get the column information from OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
I give my sql account full control permission as well.
plus I run these two as well:
USE [master]
GO
EXEC master . dbo. sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0' , N'AllowInProcess' , 1
GO
EXEC master . dbo. sp_MSset_oledb_prop N'Microsoft.ACE.OLEDB.12.0' , N'DynamicParameters' , 1
GO
2:
sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
sp_configure 'Ad Hoc Distributed Queries', 1
GO
RECONFIGURE
I would appreciate it if anyone could point me into the right direction.
strSqlQry = "Place SQL Qry Here"
vFilePath = "Database Path"
'Create Objects
Set conn = CreateObject("ADODB.Connection")
Set rs = CreateObject("ADODB.Recordset")
'Open Connection
conn.Open "Provider=Microsoft.ACE.OLEDB.12.0;" & _
"Data Source=" & vFilePath & ";" & _
"Extended Properties=""Excel 8.0;HDR=Yes;"";"
'Execute Qry
rs.Open strSqlQry, conn, adOpenStatic, adLockOptimistic
'Place recorset into excel worksheet
ActiveSheet.Range("A1").CopyFromRecordset (NewRS)
rs.Close
Set rs = Nothing
Set conn = Nothing
You can use way written in this topic How do you transfer or export SQL Server 2005 data to Excel
In excel using External data menu connect to database
The company that I work in has a new project. two of the employees will visit each store to record some information. The project is simple, We just want to insert that data, which has been collected by the two employee, to a sql database.
Unfortunately, the two employees will just have a laptop, which is offline. So, I can't use a synchronization technique to insert the data.
My solution is to allow the two employee to write the data in an excel sheet and then I try to find a way to insert that excel sheet into the sql database.
My question
is it possible to insert the excel sheet into the sql database?
is there any better solutions please?
Note
The database is very very simple, it is just a one table with three columns. ID, StoreName, and StoreProductsNumber
Or you can schedule query like this to run on server and auto sync:
INSERT INTO database..table(ID,StoreName,StoreProductsNumber)
SELECT
1 AS ID,
LTRIM(RTRIM([StoreName])),
LTRIM(RTRIM([StoreProductsNumber])),
FROM OPENROWSET('Microsoft.ACE.OLEDB.12.0', 'Excel 12.0;Database=C:\folder\excelfile.xls','select * from [sheet1$]')
Try This
public string GetDataTableOfExcel(string file_path)
{
using (OleDbConnection conn = new OleDbConnection())
{
DataTable dt = new DataTable();
string Import_FileName = Server.MapPath(file_path);
//Import_FileName = System.IO.Path.GetDirectoryName(file_path);
string fileExtension = Path.GetExtension(Import_FileName);
if (fileExtension == ".xlsx")
conn.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + Import_FileName + ";" + "Extended Properties='Excel 12.0 Xml;HDR=YES;'";
using (OleDbCommand comm = new OleDbCommand())
{
comm.CommandText = "Select * from [Sheet1$]";
comm.Connection = conn;
using (OleDbDataAdapter da = new OleDbDataAdapter())
{
da.SelectCommand = comm;
da.Fill(dt);
}
}
}
}
Now Your Data in DataTable. You can create insert query from datatable's data.
file_path is excel file's full path with directory name.
Through import functionality of SQL server u can achieve it...
http://www.mssqltips.com/sqlservertutorial/203/simple-way-to-import-data-into-sql-server/
This can be achieved using Import/Export tool. I will try and add a few stwps that can help you through the process.
Using SSMS, In the Object Explorer pane, right click on the database > Tasks > Import
Select Data Source as Microsoft Excel and Click on Browse to search and select your excel file. Fill the appropriate fields and click next
Destination will be populated as you invoked the tool from the target DB. Click Next
Select copy data from one or more tables or vies radio button and click next
Now select the Excel Tab that contains the required data and under the source and select the target table from the Destination column. Click on Edit mapping and verify if the columns are mapped to the correct destination tables. Click Next
Click finish to run the package and load data into SQL Server
You could also be interested in viewing this video that talks about the exact same thing.
http://www.youtube.com/watch?v=GG2N2iI0W3M
Hope this helps.
I have this sql code. It updates a specific cell in an excel file.
SET #cmd = 'UPDATE OPENROWSET(''Microsoft.ACE.OLEDB.12.0'',''Excel 12.0;Database=C:/sompath/file.xls;HDR=NO;IMEX=0;'',''SELECT F1,F2,F3,F4,F5,F6,F7,F8,F9 FROM [Sheet1$]'')
set [F1] = ''Hello World''
where [F1] = ''<field1>'''
EXEC(#cmd)
This piece of code executes successfully in 32bit but fails in 64bit server (MSSQL Server 2012). I get this error in 64bit:
OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)" returned message "No value given for one or more required parameters.".
Msg 7320, Level 16, State 2, Line 1
Cannot execute the query "SELECT F1,F2,F3,F4,F5,F6,F7,F8,F9 FROM [Sheet1$]" against OLE DB provider "Microsoft.ACE.OLEDB.12.0" for linked server "(null)".
The file.xls is an excel file created in a 32bit pc.
Can someone help me with this issue. I've been searching around the net but really did not get the solution or even some guide to resolving it. If this question has already been posted and answered, just kindly post the exact link please.
By the way, I have already installed the ACE provider and all those settings needed.
In fact, this code works fine but not with the UPDATE statment:
DECLARE #cmd VARCHAR(1000)
set #cmd = 'SELECT * FROM
OPENROWSET(''Microsoft.Ace.OLEDB.12.0'',
''Excel 12.0;Database=C:/sompath/file.xls;HDR=NO;IMEX=0'',[Sheet1$])'
EXEC(#cmd)
Thanks!
The excel file must be created/resaved from a 64bit MS Office. That's all!