I am importing values like 0000,0002,0023,0034 from a text file. However, the table shows them as 0, 2, 23, 34. Does anyone know why it is removing the leading zeros?
Here is my code:
private DataTable ImportTabFile()
{
string dataSourcePath = #"C:\Documents and Settings\agordon\Desktop";
string dataFileName = "ACTIVITYEX.txt";
string connString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dataSourcePath + #";Extended Properties=""text;HDR=No;FMT=Delimited""";
OleDbConnection conn = new OleDbConnection(connString);
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandText = String.Format("SELECT * FROM [{0}]", dataFileName);
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds);
return ds.Tables[0];
}
How can I keep the leading zeroes during the import?
here is what my schema file looks like:
[ACTIVITYEX.txt]
Format=TabDelimited
ColNameHeader=False
Col13=ErrorCode Text
JET will infer types based on the first row. It is probably inferring your fields are INT because 0000 can be converted to a number. As mentioned above, leading zeroes are useless.
You can use schema.ini to explicitly define the column types. As noted in the comments above, you need to specify each column as per the documentation:
You must specify each column by number and designate the column name, data type, and width for fixed-length files.
Alternatively this article has some information on controlling how the types are inferred.
Related
I've searched the internet for this and couldn't really find a question like it.I am coding an application that takes data from Excel and view it.
All of my tests were correct, but suddenly I found that Importing a column that contains set of numbers in a row then letters will result in not showing the fields that contain those letters at all
PathConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + FilePath + ";Extended Properties=\"Excel 8.0;HDR=Yes;\";";
OleDbConnection conn = new OleDbConnection(PathConn);
System.Data.DataTable dtSchema = new System.Data.DataTable();
conn.Open();
dtSchema = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
string Sheet1 = dtSchema.Rows[0].Field<string>("TABLE_NAME");
conn.Close();
OleDbDataAdapter myDataAdapter = new OleDbDataAdapter("Select * from [" + Sheet1 + "]", conn);
DataSet ds = new DataSet();
myDataAdapter.Fill(ds);
the first dataset is the regular result
7841
7847s
2344
2262
7738
JD32916
JD329161
JD318161
JD31716
JD7643
JD21116
7194
the second dataset is the problematic result (notice that I removed the 's' from "7847s")
7841
7847
2344
2262
7738
7194
as you can see, all the fields with letters in them just disappeared,
it only happens where there are 5 or more consecutive fields with no letters in them. example (2nd number from the top contains 's' to prevent that error from happening)
Use IMEX=1 in your extended properties to treat all columns as text values. Without it, the Jet provider will infer a data type based on whatever type the majority of the values in that column is, which may not be correct.
Secondly, since your data does not have a header row, you should use HDR=NO in your extended properties as well.
I'm using oledb to read from excel file.
DataTable sheet1 = new DataTable();
string excelCS = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + path + ";" + "Extended Properties=\"Excel 12.0 Xml;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"";
using (OleDbConnection connection = new OleDbConnection(excelCS))
{
connection.Open();
string selectSql = #"SELECT * FROM [Sheet1$]";
using (OleDbDataAdapter adapter = new OleDbDataAdapter(selectSql, connection))
{
adapter.Fill(sheet1);
}
connection.Close();
}
But there is a problem with some cells of the file.
For some cells I get an empty value instead of text. I tried to put some other text into these cells but it didn't work - I'm still getting empty strings.
But after deleting the column and inserting again my application get the right value of cell. Important is that the problem is not with all cells in the column.
Is this a problem with cell format or something? This excel file will be generated by another system so I won't be able to modify it manually.
Has anybody any sugestions what's wrong and what can I do?
Use IMEX = 1 at the end of your connection string. That will fix your problem.
To always use IMEX=1 is a safer way to retrieve data for mixed data
columns. .."
Remember that, sometimes there are some errors involved using IMEX while you're using Update rather than Selecting.
using this method convert Execel to Dataset without Empty String in c#
public static DataSet ConvertExcelToDataTable(string FileName)
{
DataSet ds = new DataSet();
string strConn = "";
strConn = "Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + FileName + ";Extended Properties=\"Excel 8.0; HDR=YES; IMEX=1;\"";
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Sheet1$]", strConn);
da.Fill(ds);
return ds;
}
it will return dataset.
I had this issue. What I found was that on the cells that returned blank values the data looked like strings, but the rest of the data looked like numbers, so excel stored the strings in a different place as the numbers. I changed the column format to text and all the data was picked up.
This thread might help with changing the format: Format an Excel column (or cell) as Text in C#?
The message says
The Microsoft Access database engine could not find the object
'Sheet1$'. Make sure the object exists and that you spell its name and
the path name correctly. If 'Sheet1$' is not a local object, check
your network connection or contact the server administrator.
The name of the sheet in the Worksheet is "Sheet1"
string connectionString = String.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES"";", fileName);
string query = String.Format("SELECT [columnName1],[columnName2],[columnName3] from [{0}]", "Sheet1$");
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
DataTable YourTable = dataSet.Tables[0];
listBox1.DataSource = YourTable.Columns["ColumnName1"];
This works for me:
string filename = #"C:\Book1.xlsm";
string connectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=YES\";", filename);
string query = String.Format("SELECT * from [{0}$]", "Sheet1");
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(query, connectionString);
DataSet dataSet = new DataSet();
dataAdapter.Fill(dataSet);
DataTable YourTable = dataSet.Tables[0];
*NOTE: * If your data does not have headers to make HDR=NO
Also noticed that in your question you used
[columnName1],[columnName2],[columnName3]
for your columns to select. Please remember these should be the value(s) of the first cell in the column(s) that you would like to grab.
To get column E Use:
string connectionString = String.Format("Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"Excel 8.0;HDR=NO\";", filename);
string query = String.Format("SELECT [F5] from [{0}$]", "Sheet1");
Replace 5 With any other column number you need so
F1 = A
F2 = B
F3 = C
and so on.
The Error you are getting could be because you have the file open and active.
OR you are pointing at the wrong file (Remember you have to include full file path in the filename string. and make sure the sheet is correct. Alos take notice to the fact the i include the $ in my string not in my parameter so rememer to only put just the name of the sheet you are trying to get. If you are still having trouble supply me with the FULL file name for the worksheet you are using i.e. C:\Book1.xlsm and the sheet you are trying to get data from.
Please put square brackets around Sheet1.
So your query is: select * from [Sheet1$]
I would like to change the data type in my db from "Text" to "Memo".
first of all, I didnt find the "Memo" data type in c#.
second: I got the following code to execute command in the db:
public void SQLCommand(String strSQL)
{
OleDbConnection objConnection = null;
OleDbCommand objCmd = null;
String strConnection;
strConnection = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + path + "\\tasks.mdb";
objConnection = new OleDbConnection(strConnection);
objConnection.ConnectionString = strConnection;
objConnection.Open();
objCmd = new OleDbCommand(strSQL, objConnection);
objCmd.ExecuteNonQuery();
objConnection.Close();
UpdateListView();
}
how can I change the 3rd column's data type and save it?
I can change the data type when form_load with this function:
public void tst()
{
conn.Open();
DataSet ds = new DataSet();
OleDbDataAdapter adapter = new OleDbDataAdapter("SELECT * from Tasks", conn);
adapter.Fill(ds);
DataTable dt = ds.Tables[0];
dt.Columns[3].DataType = System.Type.GetType("System.String");
conn.Close();
}
but with this function, it change to the data type to string > and I want memo.
also this function is no good since I need to run it everytime and if I change it permanently to memo I will just have to make a little if at the begining.
~Thanks.
String in C# is the equivalent of both Text and Memo in that it supports texts of either length.
If I understand the question correctly I think you're misunderstanding what you're actually doing in your code. When you set the DataType of the column, you're not changing the database in any way, you are just changing the datatype of a column in the DataTable instance that you've created.
If you actually want to change the structure of the database the best way would probably be to do it manually in Access, since I'm not sure if that's really supported in ADO.Net (I suppose you might be able to do it using ALTER statements). Otherwise you might be able to do it using DAO which used to be the Access/Jet way of doing things like that, but that was deprecated quite a while ago so might not work well in .Net.
I am reading Excel file using OLEDB in Csharp i have shown the sample excel data what i have
F1 F2 F3 F4
India 23 44 4
China 4 8 Month 6
USA 45 Neg 4
When i read this data and check in my DataTable i get Null values for "Month 6" and "Neg"
where as i can be able get the F1 column correctly... my connection string is as shown
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=[XLSource];Extended Properties=Excel 12.0;
OleDbDataReader dr;
OleDbConnection conExcel = new OleDbConnection();
conExcel.ConnectionString = ConnectionString
conExcel.Open();
OleDbCommand cmdExcel = new OleDbCommand();
cmdExcel.Connection = conExcel;
cmdExcel.CommandText = "SELECT * FROM Sheet1$";
dr = cmdExcel.ExecuteReader();
DataTable dtExcel = new DataTable();
dtExcel.Load(dr);
Try using the IMEX=1 parameter in your connection string (google for more info).
I think what's happening is that Excel is inferring the data type of each column from the first few rows. When it then encounters a value that does not match the inferred data type, it treats it as null.
I had this problem, but rather than setting IMEX=1 I set the registry setting TypeGuessRows to 0 rather than the default 8, I read that IMEX would be needed somewhere but it seems to pick up this registry change either way.
However, I am using the Jet provider rather than Ace so that might make a difference.
For me I found the setting at: Hkey_Local_Machine/Software/Microsoft/Jet/4.0/Engines/Excel/TypeGuessRows
I answered a similar question here. Here I've copied and pasted the same answer for your convenience:
I had this same problem, but was able to work around it without resorting to the Excel COM interface or 3rd party software. It involves a little processing overhead, but appears to be working for me.
First read in the data to get the column names
Then create a new DataSet with each of these columns, setting each of their DataTypes to string.
Read the data in again into this new
dataset. Voila - the scientific
notation is now gone and everything is read in as a string.
Here's some code that illustrates this, and as an added bonus, it's even StyleCopped!
public void ImportSpreadsheet(string path)
{
string extendedProperties = "Excel 12.0;HDR=YES;IMEX=1";
string connectionString = string.Format(
CultureInfo.CurrentCulture,
"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=\"{1}\"",
path,
extendedProperties);
using (OleDbConnection connection = new OleDbConnection(connectionString))
{
using (OleDbCommand command = connection.CreateCommand())
{
command.CommandText = "SELECT * FROM [Worksheet1$]";
connection.Open();
using (OleDbDataAdapter adapter = new OleDbDataAdapter(command))
using (DataSet columnDataSet = new DataSet())
using (DataSet dataSet = new DataSet())
{
columnDataSet.Locale = CultureInfo.CurrentCulture;
adapter.Fill(columnDataSet);
if (columnDataSet.Tables.Count == 1)
{
var worksheet = columnDataSet.Tables[0];
// Now that we have a valid worksheet read in, with column names, we can create a
// new DataSet with a table that has preset columns that are all of type string.
// This fixes a problem where the OLEDB provider is trying to guess the data types
// of the cells and strange data appears, such as scientific notation on some cells.
dataSet.Tables.Add("WorksheetData");
DataTable tempTable = dataSet.Tables[0];
foreach (DataColumn column in worksheet.Columns)
{
tempTable.Columns.Add(column.ColumnName, typeof(string));
}
adapter.Fill(dataSet, "WorksheetData");
if (dataSet.Tables.Count == 1)
{
worksheet = dataSet.Tables[0];
foreach (var row in worksheet.Rows)
{
// TODO: Consume some data.
}
}
}
}
}
}
}
I answered another question much like this one.
In short, the settings that control the ACE driver behavior are located in the registry at:
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Office\14.0\Access Connectivity Engine\Engines\Excel
Set ImportMixedTypes to Text and set TypeGuessRows to 0 (or some suitably large number like 1000) and you should get the behavior you are expecting.