I'm attempting to read a spreadsheet file called Book1.xls which contains a worksheet called Sheet1
However I'm getting the following error:
The Microsoft Jet database engine could not find the object 'Sheet1$'.
Make sure the object exists and that you spell its name and the path
name correctly.
Here is a snippet of the code I'm using:
Dim dt As DataTable = New DataTable()
Select Case fileExt
Case ".csv"
Dim reader As New CsvReader
dt = reader.GetDataTable(filePath)
Case ".xls", ".xlsx"
Dim oleDbConnStr As String
Select Case fileExt
Case ".xls"
oleDbConnStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & filePath & ";Extended Properties=""Excel 8.0;HDR=Yes;IMEX=2"""
Case ".xlsx"
oleDbConnStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" & filePath & ";Extended Properties=""Excel 12.0;HDR=Yes;IMEX=2"""
End Select
Using oleDbConn As OleDbConnection = New OleDbConnection(oleDbConnStr)
oleDbConn.Open()
Dim oleDbCmd As New OleDbCommand("SELECT * FROM [Sheet1$]", oleDbConn)
Dim oleDbDa As New OleDbDataAdapter(oleDbCmd)
oleDbDa.Fill(dt)
oleDbConn.Close()
End Using
End Select
I can't understand why the code cannot find my worksheet. Why is this, and how can I resolve it?
I've found the problem.
It seems the spreadsheet was being saved to the wrong location, so filepath wasn't pointed to a file which exists.
I didn't check this at first because I assumed a different error message would appear. Something like "Book1.xls could not be found". However it seems like if it doesn't exist, then the message will just state that it cannot find the Worksheet.
If file name has additional dot character like below:
sample.data.csv
next select statement:
SELECT * FROM [sample.data.csv]
with connection string:
Provider=Microsoft.Jet.OLEDB.4.0;Data Source="C:\Data\"; Extended Properties="text;HDR=Yes;Format=Delimited;";
will fail with exception:
Additional information: The Microsoft Jet database engine could not find the object 'sample.data.csv'. Make sure the object exists and that you spell its name and the path name correctly.
Also - make sure you don't have the file open in Excel already. You won't be able to read the file if it's open somewhere else. I had the same error and realized I had the file open in Excel.
Not sure, I have some similar code (C#) that works well...
Maybe you can spot a difference?
string connectionString = string.Format(Thread.CurrentThread.CurrentCulture, "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 12.0;HDR=YES;'", excelFilePath);
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
using (DbConnection connection = factory.CreateConnection())
{
connection.ConnectionString = connectionString;
using (DbCommand command = connection.CreateCommand())
{
command.CommandText = #"SELECT [File], [ItemName], [ItemDescription], [Photographer name], [Date], [Environment site] FROM [Metadata$]";
connection.Open();
using (DbDataReader dr = command.ExecuteReader())
{
if (dr.HasRows)
{
while (dr.Read())
{
.......
}
}
}
connection.Close();
}
}
Try renaming your sheet; or explicitly adding columns; or checking if it's case sensitive.
Change your Excel file location, this error will be resolved.
may put your file in the same folder where your source present
best solution through vb coded from this link, all credits to these folks-
http://www.vbforums.com/showthread.php?507099-data-from-excel-sheet-to-datagrid-(vb)
C# My expected solution below
string connString = "Driver={Microsoft Excel Driver (*.xls)};READONLY=FALSE;DriverId=790;Dbq=" + "C:\\Users\\BHARAVI\\Documents\\visual studio 2013\\Projects\\ERP\\ERPAutomation\\Assets\\Data\\Data.xls";
OdbcConnection conn = new OdbcConnection(connString);
conn.ConnectionTimeout = 500;
OdbcCommand CMD = new OdbcCommand("SELECT * FROM [Sheet1$]", conn);
OdbcDataAdapter myDataAdaptor = new OdbcDataAdapter(CMD);
DataSet ds = new DataSet();
myDataAdaptor.Fill(ds ,"Sheet1");
DataTable dt = ds.Tables[0];
foreach (DataRow dr in dt.Rows)
{
loginId = dr["LoginId"].ToString();
encryptedPassword = dr["PWD"].ToString();
URL = dr["URL"].ToString();
}
Related
I am trying to read an Excel page but I get the following error:
Input string was not in a correct format.Couldn't store <555-555-5555> in PHONE_NUM Column. Expected type is Double.
It seems that the oledb command is expecting the column to be of type double (but, in fact, it is a string for phone numbers). I think I read somewhere that this happens because the command looks as the first couple of items in the column and determines what the type should be based off of that. Is there anyway to always read all values in as a string?
This is the code I am using:
Dim connection As OleDb.OleDbConnection
Dim command As OleDb.OleDbCommand
Dim adapter As New OleDb.OleDbDataAdapter
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + myFile + ";Extended Properties=Excel 12.0;"
Dim pgOne As String = "Page1$"
Dim pgTwo As String = "Page2$"
Dim selectOne As String = "SELECT * FROM [" & pgOne & "] WHERE COL1<>''"
Dim selectTwo As String = "SELECT * FROM [" & pgTwo & "]"
connection = New OleDb.OleDbConnection(connString)
Try
If connection.State = ConnectionState.Open Then
Else
connection.Open()
End If
command = New OleDb.OleDbCommand(selectOne, connection)
adapter.SelectCommand = command
adapter.Fill(ds, "Table1")
adapter.SelectCommand.CommandText = selectTwo
adapter.Fill(ds, "Table2")
Catch ex As OleDb.OleDbException
Finally
adapter.Dispose()
If (Not command Is Nothing) Then
command.Dispose()
End If
connection.Close()
End Try
You can get the tables to fill as strings in one of two ways. If you want to read them in as only a string you can add a part to your connection string that should read intermixed datatype columns as text. Alternatively force them into string types by reading in a header row as data. You can also use schemas to read in table definitions but I would need to find a little more info on that if these don't work for you.
The first option is simpler to do:
First change your connection string to add IMEX=1
'Add IMEX=1
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;IMEX=1;Data Source=" + myFile + ";Extended Properties=Excel 12.0;"
This should then provide you with String based columns on any datacolumns that have mixed data types in their rows.
Another way to do it is force the string column type by reading the header row as a datarow by specifying there is no header row in your connection string. You can then remove this after to have a string column of data.
'Add HDR=NO
Dim connString As String = "Provider=Microsoft.ACE.OLEDB.12.0;HDR=NO;Data Source=" + myFile + ";Extended Properties=Excel 12.0;"
I will research a little more if these don't work for you.
As mentioned, I was unable to fix this so I just ended up creating a schema manually and formatting the data as it was bound.
I have scoured the net, and found many people asking this, yet none have fixed my answer.
I have a Connection Class, and a Method that uses that Class in a page.
DataConn.cs
public static OleDbConnection ConnectExcel()
{
//Store the connection details as a string
string connstr =
String.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=pricelist.xlsx;Extended Properties=Excel 12.0 Xml;HDR=YES");
//Initialise the connection to the server using the connection string.
OleDbConnection oledbConn = new OleDbConnection(connstr);
//Open the connection, we do this here so we can instantly be able to use SQL commands in the code.
oledbConn.Open();
return oledbConn;
}
public static void DisconnectExcel()
{
_oledbConn.Dispose();
_oledbConn.Close();
}
And the code that calls it
protected void Page_Load(object sender, EventArgs e)
{
// Connection String
const string xlStr = "SELECT * FROM [Sheet2$]";
// Create OleDbCommand object and select data from worksheet Food
OleDbCommand cmd = new OleDbCommand(xlStr, DataConn.ConnectExcel());
// Create new OleDbDataAdapter
OleDbDataAdapter oleda = new OleDbDataAdapter();
oleda.SelectCommand = cmd;
// Create a DataSet which will hold the data extracted from the worksheet.
DataSet ds = new DataSet();
// Fill the DataSet from the data extracted from the worksheet.
oleda.Fill(ds);
// Bind the data to the GridView
gridPricelist.DataSource = ds;
gridPricelist.DataBind();
}
Yes I STILL get:
System.Data.OleDb.OleDbException: Could not find installable ISAM.
Can anyone please help?
If you use more than 1 extended property then the value tokens must be quoted, otherwise there is no way for the driver to distinguish them from the other non-extended properties in the connection string;
...Extended Properties=""Excel 8.0;IMEX=1"""
modify your connection string
String.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=pricelist.xlsx;Extended Properties=""Excel 12.0 Xml;HDR=YES""");
reference:
Could not find installable ISAM
please "Extended Properties" put it in ' '.
That is, like the following statement:
string connStr =
String.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=pricelist.xlsx;Extended Properties='Excel 12.0
Xml;HDR=YES'")
If you had installed LibreOffice look for cli_basetypes.dll, cli_cppuhelper.dll, cli_oootypes.dll, cli_uno.dll, cli_ure.dll, cli_uretypes.dll then add references to your project (to work with LibreOffice API's), I also installed "Microsoft Office Compatibility Pack for Word, Excel, and PowerPoint File Formats" and "Microsoft Access Database Engine 2010 Redistributable" (to get ACE.OLEDB.12.O connection without complete Office installation). This is a part of VB Sample in which I got the connection to oledb to create some queries.
OpenFileDialog.Filter = "Spreadsheets (*.xls*)|*.xls*"
OpenFileDialog.Multiselect = False
Try
If (OpenFileDialog.ShowDialog() = System.Windows.Forms.DialogResult.OK) Then
objOffice = CreateObject("com.sun.star.ServiceManager") 'preparar instancia libreOffice (prepare libreOffice instance)
instOffice = objOffice.createInstance("com.sun.star.frame.Desktop")
Dim obj(-1) As Object
Dim myDoc = instOffice.loadComponentFromURL("file:///" & OpenFileDialog.FileName.Replace("\", "/"), "_default", 0, obj)
Dim hojas = myDoc.getSheets().getElementNames() 'Obtener nombres de las hojas de calculo (get Spreadsheet names)
System.Threading.Thread.Sleep(1000) 'Esperar a que termine la instancia Office (await libreOffice thread)
myDoc.Close(True)
Dim MyConnection As System.Data.OleDb.OleDbConnection 'Preparar conexión para realizar consulta tipo sql (preparing connection)
Dim DtSet As System.Data.DataSet
Dim MyCommand As System.Data.OleDb.OleDbDataAdapter
If OpenFileDialog.FileName.ToUpper.Contains(".XLSX") Then
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & OpenFileDialog.FileName & "';Extended Properties='Excel 12.0 Xml;HDR=YES;IMEX=1;'")
Else
MyConnection = New System.Data.OleDb.OleDbConnection("provider=Microsoft.ACE.OLEDB.12.0;Data Source='" & OpenFileDialog.FileName & "';Extended Properties='Excel 12.0;HDR=YES;IMEX=1'")
End If
Sorry my Enghist is not good!
How to check excel fie, if a row existing in table do'nt import this row
My function work well for import (not check existing)
string excelConnectionString = "";
string strFileName = DateTime.Now.ToString("ddMMyyyy_HHmmss");
string strFileType = System.IO.Path.GetExtension(fileuploadExcel.FileName).ToString().ToLower();
fileuploadExcel.SaveAs(Server.MapPath("~/Import/" + strFileName + strFileType));
string strNewPath = Server.MapPath("~/Import/" + strFileName + strFileType);
//Connection String to Excel Workbook
if (strFileType.Trim() == ".xls")
{
excelConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strNewPath + ";Extended Properties=Excel 8.0;Persist Security Info=False";
}
else if (strFileType.Trim() == ".xlsx")
{
excelConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + strNewPath + ";Extended Properties=Excel 12.0;Persist Security Info=False";
}
//Create Connection to Excel work book
OleDbConnection excelConnection =new OleDbConnection(excelConnectionString);
//Create OleDbCommand to fetch data from Excel
OleDbCommand cmd = new OleDbCommand("Select [account_id], [type],[first_name], [last_name], [title], [birthday], [tel],[phone], [email_1],[email_2], [remark],[del_if] from [Sheet1$]",excelConnection);
excelConnection.Open();
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection);
//Give your Destination table name
sqlBulk.DestinationTableName = "contact";
sqlBulk.WriteToServer(dReader);
I don't know if this is going to be possible using SqlBulkCopy. What you could do, is write the data to a staging table, and only copy across the records that don't already exist. Then you can clear out the staging table once your copy is complete.
Edit:
Given your comment about not wanting to use a staging table, you could possibly find a distinct list of key values (possibly account_id from your example) from your "contact" table before reading data from the excel file, and then use the list to exclude records you read from the excel file. The benefits to this are you aren't reading data from the excel file that you don't need to. The downside is that this might not be all that efficient if your "contact" table is huge or if the key you'd use to compare the data isn't something simple like account_id.
Another alternative could be, if you're excel file isn't huge, to insert records row by row using a where clause on the insert to ensure the insert won't create unnecessary duplicates. This will be significantly slower than SqlBulkCopy, but it'll work.
Here's the code I'm using to show the Excel data on a Gridview:
if (FileUploadExcel.PostedFile.FileName.Contains(".xls"))
{
FileUploadExcel.SaveAs(Server.MapPath("~/Upload/") + "data.xls");
string connectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + Server.MapPath("~/Upload/") + "data.xls;Extended Properties=Excel 8.0;";
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
connection.Open();
OleDbCommand command = new OleDbCommand("Select ID FROM [Sheet1$]", connection);
DataTable raw = new DataTable();
using (System.Data.Common.DbDataReader dr = command.ExecuteReader())
{
raw.Load(dr);
}
gv.DataSource = raw;
gv.DataBind();
}
}
This is what happens... I have this in my data.xls file:
ID
A-001
3929
B-001
When I upload that, the Gridview displays only these:
ID
A-001
B-001
Is there anything wrong with the code? Thanks.
Try to add IMEX=1 to your connection string.
It tells the driver to always read "intermixed" (numbers, dates, strings etc) data columns as text. Note that this option might affect excel sheet write access negative.
http://www.connectionstrings.com/excel
I'm importing data from an Excel file in ASP.NET using OleDB. After finishing the import, I want to delete the file using the command System.IO.File.Delete(), but it throws the following exception:
The process cannot access the file '...29.xls' because it is being used by another process.
I used the following code to open and close the file:
Dim fajl As String
fajl = MapPath("fajlovi/" + Request.QueryString("ID"))
Dim sConnectionStringExcel As String = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" & fajl & ";Extended Properties=Excel 8.0;"
Dim objConnExcel As New OleDbConnection(sConnectionStringExcel)
objConnExcel.Open()
Dim objCmdSelectExcel As New OleDbCommand("SELECT ZavedenKodPov, Ime, Mjesto, Adresa, JMBG, LicniBroj, ZaposlenKod, Nepoznat, Umro, Penzioner, Reon, VoziloProizvodjac, VoziloModel, VoziloRegistracija, Nekretnina, Datum, KontoBroj, NazivKonta, OpisPromjene, Dug, Pot FROM [Sheet1$]", objConnExcel)
Dim objAdapterExcel As New OleDbDataAdapter()
objAdapterExcel.SelectCommand = objCmdSelectExcel
Dim objDatasetExcel As New DataSet()
objAdapterExcel.Fill(objDatasetExcel, "XLData")
Dim tExcel As DataTable
tExcel = objDatasetExcel.Tables(0)
'.
'.
'.
objConnExcel.Close()
System.IO.File.Delete(fajl)
Any ideas what I'm doing wrong?
dispose of the command and connection, preferably wrapped in a using statement. then you should be able to delete the file.