I am using following code for excel upload
OleDbConnection sSourceConnection;
string properties = "Excel 8.0; HDR=NO; IMEX=1;";//properties set for connection to excel
string sSourceConstr = #"Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + filePath + ";Extended Properties=\"" + properties + "\"";
sSourceConnection = new OleDbConnection(sSourceConstr);//creating the OLEDB connection
try
{
//select statement to select data from the first excel sheet
string sql = string.Format("Select * FROM [{0}]", "Sheet1$");
//commands to fill the dataset with excel data
OleDbDataAdapter excelAdapter = new OleDbDataAdapter();
OleDbCommand command = new OleDbCommand(sql, sSourceConnection);
sSourceConnection.Open();
excelAdapter.SelectCommand = command;
excelAdapter.Fill(dSet, EXCEL_DATA);
I have to upload around 300 records. One column has some text comments. The length of comments varies from 10 chars to 1000 chars. But all of comments above 255 length are getting truncated in that column.
I have used this post Excel cell-values are truncated by OLEDB-provider to change a registry setting, but it didn't work.
I have also tried everything mentioned in the post OleDB & mixed Excel datatypes : missing data, still nothing works.
I was using ACE engine so the correct place to update the registery is
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRowsHKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel\TypeGuessRows
For Microsoft Office 2010-2013-2016/365
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel
And better is to scan for the text ‘TypeGuessRows’ and when you find it, in combination with Excel, set its value to 0. We’ve found another important location for this behavior at this location
\HKEY_LOCAL_MACHINE \SOFTWARE\Microsoft\Office \ClickToRun\REGISTRY \MACHINE\Software \Wow6432Node \Microsoft \Office\16.0\Access Connectivity Engine\Engines\Excel.
Related
My requirement is to read a excel file from a local folder and import into DataTable. Importing work fine if the first row contains string value, If the value is int in first 3 rows the datatype of column becomes Integer and it is ignoring string values. I want to read a the values. I tried to insert a row of string values, but due to int datatype its not allowing. Plz help.. i am in a big trouble.
I Tried with IMEX=1 in connection string, but no go
string Extension = ".xlsx";
string conStr = "";
switch (Extension)
{
case ".xls": //Excel 97-03
conStr = ConfigurationManager.ConnectionStrings["Excel03ConString"].ConnectionString;
break;
case ".xlsx": //Excel 07
conStr = ConfigurationManager.ConnectionStrings["Excel07ConString"].ConnectionString;
break;
}
conStr = String.Format(conStr, strPath);
oledbConn = new OleDbConnection(conStr);
if (oledbConn.State != ConnectionState.Open)
oledbConn.Open();
OleDbCommand cmd = new OleDbCommand(); ;
OleDbDataAdapter oleda = new OleDbDataAdapter();
DataTable dt = new DataTable();
dt.Columns.Add("Store", typeof(string)).DefaultValue = strPath.Substring(18, 3);
var sheets = oledbConn.GetOleDbSchemaTable(System.Data.OleDb.OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
cmd.Connection = oledbConn;
cmd.CommandType = CommandType.Text;
cmd.CommandText = " SELECT * FROM [" + sheets.Rows[0]["TABLE_NAME"].ToString() + "] ";
oleda = new OleDbDataAdapter(cmd);
//oleda.FillSchema(dt, SchemaType.Source);
dt.TableName = strPath.Substring(18, 3);
oleda.Fill(dt);
This unfortunately comes down to registry settings used when using the Jet or ACE engines to import from Excel (and other file types). The engine will scan the first N rows of data (controlled by a registry value called TypeGuessRows, which defaults to 8), and use this to determine what it thinks the data type of each column is. If within the first TypeGuessRows rows of the spreadsheet it detects multiple types, it will then use the ImportMixedTypes setting (whose only valid values are Text and MajorityType, and Text is what you want here).
The simplest option for you here is probably to increase that TypeGuessRows setting. But if the spreadsheets you need to work with contain tens of thousands of rows, you'll have a problem as I believe that it won't sample more than 16,384 rows regardless. And if it doesn't think a particular column is mixed type, then it won't treat apply the ImportMixedTypes setting (so if you've got 20,000 rows, and the first 17000 are all int, that column is staying int even if the last 3000 aren't integers, and you'll get nulls in their place). Formatting the column in Excel will have no effect, nor will specifying a destination data type.
You may need to change the setting(s) in multiple places, depending on your connection string and the version of Excel or the Access Connectivity Engine installed. On Windows 7 64-bit, for example, the location for the Jet setting in the registry is HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Jet\4.0\Engines\Excel.
There are similar locations for using the ACE engine, depending on the version of Excel.
More information here, both in the old blog post and the more recent comments.
Basically, importing from files using Jet/ACE can be a painful experience and some of the time you might not even notice there's a problem.
I am using OLEDB to read excel file into datatable. But the problem is, some values are missing(Empty). In my excel sheet one column datatype is General, it has mixed values like string and integers. Most of the cell values are integers. Why OLEDB is skipping string values.
OleDbConnection connection = new OleDbConnection();
connection.ConnectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + "; Extended Properties=\"Excel 12.0;IMEX=1\";";
OleDbCommand myAccessCommand = new OleDbCommand();
myAccessCommand.CommandText = "Select * from [" + sheetName + "]";
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter(myAccessCommand);
myDataAdapter.Fill(myDataSet);
Check following link and see points under "RESOLUTION":
http://support.microsoft.com/kb/194124
Please see point 2 NOTE.
Setting IMEX=1 is entirely dependent on your registry settings. By default, first 8 rows are checked to determine the data type. IMEX=1 can give unpredictable behaviors, such as skipping string values. There is also one small workaround for this problem. Just add single quote (') before every cell value in excel. Every cell will be treated as string.
Add IMEX=1 to the connection string as below:
string con = string.Format(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};" + #"Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'", fileName);
I am using OLE related API's for reading data to DataSet and later to view in DataGridView. The source is an excel file. If the first row or column is empty than that row or column is getting skipped. I wish to read the data irrespective of empty/has data. Other rows/columns even if its empty its working fine, but only starting is missing.
I read about ColumnHeader and tried changing connectionString (HDR=NO) and others but nothing worked out.
Any additional things need to be specified while calling the API? One to one mapping with the excel column and the DataGridView column is missing because of skipping this initial blank rows/columns.
Anything needs to be added/modified to this OleDbDataAdapter parameter, which actually reads the data and fills to dataset:
OleDbDataAdapter cmd = new System.Data.OleDb.OleDbDataAdapter(
"select * from [" + worksheetName + "$]", con);
Yes, I am setting some required information and calling a method to read data from each sheet. I am not doing any action on the rows/columns except reading them.
OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);
System.Data.DataTable getWorksheetData(OleDbConnection con, OleDbDataAdapter cmd)
{
con.Open();
System.Data.DataSet excelDataSet = new DataSet();
cmd.Fill(excelDataSet);
con.Close();
return excelDataSet.Tables[0];
}
My connection string is:
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
fileName + "; Extended Properties=\"Excel 12.0 Xml;HDR=NO;Mode=Read;ReadOnly=True;\"";
I have a excel table with 1 sheet. That sheet has headers in row 1.
One of the headers is Amount.
I want to read all rows from that header and get the sum of it independently of the number or rows, which is never the same, into a variable of type float.
I'm doing this with c#.
I open the workbook, I get the active sheet and then nothing, I get blocked.
How do I go about this?
Rui Martins
You could use OleDB instead of Excel.Interop
string con = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\test.xls;" +
"Extended Properties='Excel 8.0;HDR=Yes;'";
using(OleDbConnection c = new OleDbConnection(con))
{
c.Open();
string selectString = "SELECT SUM(Amount) FROM [Sheet1$]";
using(OleDbCommand cmd1 = new OleDbCommand(selectString))
{
cmd1.Connection = c;
var result = cmd1.ExecuteScalar();
Console.WriteLine(result);
}
}
This example use the old Microsoft.Jet.OleDB.4.0 provider, but works equally with the new Microsoft.ACE.OLEDB.12.0
Take a look at this article, you should be able to loop through the rows and get the total by adding the cell values altogether.
MSDN article on how to retrieve excel cell values.
As part of a project I'm working on in C# I need to read in a .dbf file. The first thing I want to do is to get the schema table from the file. I have code that works as long as the filename (without the extension) is not longer than 8 characters.
For example, let's say I have a file named MyLongFilename.dbf. The following code does not work; it throws the following exception: “The Microsoft Jet database engine could not find the object 'MyLongFilename'. Make sure the object exists and that you spell its name and the path name correctly.”
string cxn = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyLongFilename;Extended Properties=dBASE 5.0";
OleDbConnection connection = new OleDbConnection(cxn);
To get past this exception, the next step is to use a name the OldDbConnection likes ('MyLongF~1' instead of 'MyLongFilename'), which leads to this:
string cxn = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=C:\MyLongF~1;Extended Properties=dBASE 5.0";
OleDbConnection connection = new OleDbConnection(cxn);
This does successfully return an OleDbConnection. Now to get the schema table I try the following:
connection.Open();
DataTable schemaTable = connection.GetOleDbSchemaTable(OleDbSchemaGuid.Columns,
new object[] { null, null, fileNameNoExt, null });
This returns a DataTable with no rows. If I rename the filename to 8 or less characters then this code works and I get back a row for each field in the database.
With the long filename, I know the returned connection is valid because I can use it to fill a DataSet like so:
string selectQuery = "SELECT * FROM [MyLongF~1#DBF];";
OleDbCommand command = new OleDbCommand(selectQuery, connection);
connection.Open();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter();
dataAdapter.SelectCommand = command;
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
This gives me back a DataSet containing a DataTable with all of the data from the dbf file.
So the question is how can I get just the schema table for the long named dbf file? Of course I can work around the issue by renaming/copying the file, but that’s a hack I don’t want to have to make. Nor do I want to fill the DataSet with the top 1 record and deduce the schema from columns.
According to MSDN, the folder represents the database and the files represent tables. You should be using the directory path not including the filename in the connection string then, and the name of the table as part of the restrictions to GetOleDbSchemaTable.
Well, i think the connection should be
string cxn = "PROVIDER=Microsoft.Jet.OLEDB.4.0;Data Source=C:\;Extended Properties=dBASE 5.0";
OleDbConnection connection = new OleDbConnection(cxn);
and the other is, maybe you should try with other provider, I boosted a lot along ago when I used like this:
string cxn = "PROVIDER=VFPOLEDB.1;Data Source=C:\;Extended Properties=dBASE 5.0";
But you should have VFP 7 installed
or install Microsoft OLE DB Provider for Visual FoxPro 9.0 from here
const string connectionString = #"Provider = vfpoledb; Data Source = {0}; Collating Sequence = general;";
OleDbConnection conn = new OleDbConnection(string.Format(connectionString, dirName));
conn.Open();
OleDbCommand cmd = new OleDbCommand(string.Format("select * from {0}", fileName), conn);
Is fileNameNoExt holding the short filename version? Also, MyLongF~1 is 9 characters, not 8.
If you have a single (and possibly small) dbf file you can solve the problem copying the dbf file elsewhere and open the copy instead of the original file.
I believe that the DataSource should represent the directory that contains the .DBF files. Each .DBF file corresponds to a table in that directory.
My guess is c:\MyLongF~1 is a short name for a directory that contains a filename corresponding to MyLongF~1#DBF
Can you verify whether or not this is the case?