The Microsoft Jet database engine could not find the object 'Sheet1$_' - c#

I am reading data from an Excel file. when I read the normal Excel file,It works fine but when I read an excel file which has columns like shown below it does not find the work sheet and gives an exception-
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.
My Code to read the excel is-
private static DataTable getExcelData(string ExcelPath)
{
OleDbConnection con;
string connectionString;
string[] pathArray = ExcelPath.Split('.');
var Extention = pathArray[pathArray.Length - 1];
if (Extention == "xlsx")
//read a 2007 file
connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
ExcelPath + ";Extended Properties=\"Excel 8.0;HDR=YES;\"";
else
//read a 97-2003 file
connectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" +
ExcelPath + ";Extended Properties=Excel 8.0;";
con = new OleDbConnection(connectionString);
if (con.State == ConnectionState.Closed)
{
con.Open();
}
DataTable dbSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Columns, null);
var firstSheetName = dbSchema.Rows[0]["TABLE_NAME"];
OleDbDataAdapter cmd = new OleDbDataAdapter("select * from [" + firstSheetName + "] Where NOT [Event Code]=''", con);
DataSet ds = new DataSet();
cmd.Fill(ds);
con.Close();
return ds.Tables[0];
}
}
I have to get all the columns inside Mon,Tues etc.

GetOleDbSchemaTable also returns hidden tables in your Excel file: usually a name like Sheet1$_ indicates an hidden table created when you apply a filter on Sheet1$.
You need to change your code: search for table that ends with $ to set firstSheetName.
Please note that OLEDB does not preserve the sheet order as they were in Excel.
Also note that you need to do this to read an excel file with multirow titles:
set HDR=No in EXTENDED PROPERTIES of your connection string
specify column name and select range in your OleDbCommand in order to skip the first two rows
For example:
SELECT [F1] AS Location,
[F2] AS EmpId,
[F3] AS EmpName,
[F4] AS MondayShift,
[F5] AS Monday15Min,
[F6] AS Monday30Min,
[F7] AS Monday15Min2
FROM [Sheet1$A3:G]

Related

Showing extra rows in database after importing to SQL Server

I'm building a program that needs the following features:
Import an Excel file into database -- Check
Avoid duplicates --- working on it
Ignore some rows that are in the header of the Excel file and the bottom --- that's what I want to ask you guys
Here's my code
protected void Upload_Click(object sender, EventArgs e)
{
string excelPath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.PostedFile.FileName);
string filepath = Server.MapPath("~/Nova pasta/") + Path.GetFileName(FileUpload1.FileName);
string filename = Path.GetFileName(filepath);
FileUpload1.SaveAs(excelPath);
string strConnection = #"Data Source=PEDRO-PC\SQLEXPRESS;Initial Catalog=costumizado;Persist Security Info=True;User ID=sa;Password=1234";
string excelConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0 Xml;HDR=NO,IMEX=1;\"";
OleDbConnection excelConnection = new OleDbConnection(excelConnectionString);
excelConnection.Open();
DataTable schema = excelConnection.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string sheetName = schema.Rows[0]["TABLE_NAME"].ToString();
OleDbCommand cmd = new OleDbCommand("Select * from [" + sheetName + "]", excelConnection);
OleDbDataReader dReader;
dReader = cmd.ExecuteReader();
using (SqlBulkCopy sqlBulk = new SqlBulkCopy(strConnection))
{
sqlBulk.ColumnMappings.Add(0,0);
sqlBulk.ColumnMappings.Add(1,1);
sqlBulk.ColumnMappings.Add(2,2);
sqlBulk.ColumnMappings.Add(3,3);
sqlBulk.DestinationTableName = "Dados";
sqlBulk.WriteToServer(dReader);
}
excelConnection.Close();
}
And what I'm struggling is that I need to my code to find the columns in the excel and ignore the rows that I don't need...
I thought that this lines were enough for the job :
sqlBulk.ColumnMappings.Add(0,0);
sqlBulk.ColumnMappings.Add(1,1);
sqlBulk.ColumnMappings.Add(2,2);
sqlBulk.ColumnMappings.Add(3,3);
sqlBulk.DestinationTableName = "Dados";
Here's the table that I want to import :
Dealing with fluctuating source files is tricky. Maybe try loading the file as a whole into a raw table and then after loading the table call a proc to only move the columns that match complete row to your prod or final table. For example, only select from raw where Data Mov, Data Valor, Descricao do Movimento, and Valor em EUR are not null. If needed you could add more validation if needed, like checking the first two columns for date format and the last column for a numeric value. I just think it might be easier to do it in SQL than in .NET code.

How to insert data from excel to datatable which has headers?

I am reading excel having like million of records first i query my table (no records) and get Datable. i query my table to get columns name as define in my excel sheet using alias.
var dal = new clsConn();
var sqlQuery = "SELECT FETAPE_THEIR_TRANDATE \"Date\" ,ISSUER Issuer, ISSU_BRAN Branch , STAN_NUMB STAN, TERMID TermID, ACQUIRER Acquirer,DEBIT_AMOUNT Debit,CREDIT_AMOUNT Credit,CARD_NUMB \"Card Number\" , DESCRIPTION Description FROM ALLTRANSACTIONS";
var returntable = dal.ReadData(sqlQuery);
DataRow ds = returntable.NewRow();
var dtExcelData = returntable;
So my datatable looks like this,
Then i read records from excel sheet
OleDbConnection con = null;
if (ext == ".xls")
{
con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filepath + ";Extended Properties=Excel 8.0;");
}
else if (ext == ".xlsx")
{
con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0;IMEX=2;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"");
}
con.Open();
dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string getExcelSheetName = dt.Rows[0]["Table_Name"].ToString();
//OleDbCommand ExcelCommand = new OleDbCommand(#"SELECT * FROM [" + getExcelSheetName + #"]", con);
OleDbCommand ExcelCommand = new OleDbCommand("SELECT F1, F2, F3, F4, F5,F6,F7,F8,F9,F10 FROM [Sheet1$]", con);
OleDbDataAdapter ExcelAdapter = new OleDbDataAdapter(ExcelCommand);
try
{
ExcelAdapter.Fill(dtExcelData); //Here I give the datatable which i made previously
}
catch (Exception ex)
{
//lblAlert2.CssClass = "message-error";
//lblAlert2.Text = ex.Message;
}
It reads successfully and fill data in datatable but creating its own column in data table like F1 to F10 how can i move this data to exactly match with my defined columns in datatable
How Will i manage this to not create other columns (f1,f2..f10)
any workaround will be appreciable or Please explain what i am doing wrong and how can i achieve this.
UPDATE :
My Excel file looks like this
The Microsoft.ACE.OLEDB.12.0 driver will handle both types of excel spreadsheets and using the same Extended Properties. i.e. "Excel 12.0" will open both .xls and .xlsx.
Leave the HDR=NO as OLEDB expects them in the first row and they are actually in row 11.
Sadly "TypeGuessRows=0;ImportMixedTypes=Text" is completely ignored by Microsoft.ACE.OLEDB.12.0, you've got to play around with the registry (yuk). Change your IMEX=2 to IMEX=1 to ensure that mixed data types as handled as text.
Change back to using "Select * From [Sheet1$]" and then I'm afriad that you are going to have to handle the source data manually.
OleDbConnection con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filepath + ";Extended Properties=\"Excel 12.0;IMEX=1;HDR=NO\"");
con.Open();
DataTable dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
string getExcelSheetName = (string)dt.Rows[0]["Table_Name"];
DataTable xlWorksheet = new DataTable();
xlWorksheet.Load(new OleDbCommand("Select * From [" + getExcelSheetName + "]", con).ExecuteReader());
//More than 11 rows implies 11 header rows and at least 1 data row
if (xlWorksheet.Rows.Count > 11 & xlWorksheet.Columns.Count >= 10)
{
for (int nRow = 11; nRow < xlWorksheet.Rows.Count; nRow++)
{
DataRow returnRow = returntable.NewRow();
for (int nColumn = 0; nColumn < 10; nColumn++)
{
//Note you will probably get conversion problems here that you will have to handle
returnRow[nColumn] = xlWorksheet.Rows[nRow].ItemArray[nColumn];
}
returntable.Rows.Add(returnRow);
}
}
I'm guessing you simply want to add the excel data into your ALLTRANSACTION table? You don't specify but it seems the likely outcome of this. If so this is a terrible way to do it. You don't need to read the whole table into memory append data and then update the database. All you need to do is read the excel file and insert the data to the Oracle table.
Some thoughts, your returntable will contain data so if you just want the structure of the table then add a "Where RowNum=0" to the Select statement. To add the data to your Oracle Database you could 1) Convert to using the Oracle Data Provider (ODP) and then use using OracleBulkCopy Class or 2) simply modify the above to insert row by row as you read the data. As long as you don't have a LOT of data in your Excel spreadsheet it will work just fine. Having said that a Million rows is a LOT so perhaps not the best option. You will need to validate the input as Excel is not the best data source really.

Search a row from a table which starts with asterisk symbol

I am uploading an excel file by using c# and i am selecting a column named LOT from that excel file.In column LOT one row is having number starting with asterisk symbol(*). I need a query to select all the rows. please Help me out in this.
I tried the below sample code but it is not working fine. Its returning the lots which doesn't have asterisk symbol(*).
protected void btnUpload_Click(object sender, EventArgs e)
{
//Get path from web.config file to upload
string FilePath = ConfigurationManager.AppSettings["FilePath"].ToString();
string filename = string.Empty;
//To check whether file is selected or not to uplaod
if (BrowseFile.HasFile)
{
try
{
string[] allowdFile = { ".xls", ".xlsx" };
//Here we are allowing only excel file so verifying selected file pdf or not
string FileExt = System.IO.Path.GetExtension(BrowseFile.PostedFile.FileName);
//Check whether selected file is valid extension or not
bool isValidFile = allowdFile.Contains(FileExt);
if (!isValidFile)
{
lblMsg.ForeColor = System.Drawing.Color.Red;
lblMsg.Text = "Please upload only Excel";
}
else
{
// Get size of uploaded file, here restricting size of file
int FileSize = BrowseFile.PostedFile.ContentLength;
if (FileSize <= 1048576)//1048576 byte = 1MB
{
//Get file name of selected file
filename = Path.GetFileName(Server.MapPath(BrowseFile.FileName));
//Save selected file into server location
BrowseFile.SaveAs(Server.MapPath(FilePath) + filename);
//Get file path
string filePath = Server.MapPath(FilePath) + filename;
//Open the connection with excel file based on excel version
OleDbConnection con = null;
if (FileExt == ".xls")
{
con = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + filePath + ";Extended Properties=Excel 8.0;");
}
else if (FileExt == ".xlsx")
{
con = new OleDbConnection(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + filePath + ";Extended Properties=Excel 12.0;");
}
con.Open();
//Get the list of sheet available in excel sheet
DataTable dt = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
//Get first sheet name
string getExcelSheetName = dt.Rows[0]["Table_Name"].ToString();
//Select rows from first sheet in excel sheet and fill into dataset
//OleDbCommand ExcelCommand = new OleDbCommand(#"SELECT LOT FROM [" + getExcelSheetName + #"] WHERE LOT IS NOT NULL", con);
OleDbCommand ExcelCommand = new OleDbCommand(#"SELECT LOT FROM [" + getExcelSheetName + #"] WHERE LOT LIKE '**'", con);
OleDbDataAdapter ExcelAdapter = new OleDbDataAdapter(ExcelCommand);
DataTable ExcelDataSet = new DataTable();
ExcelAdapter.Fill(ExcelDataSet);
//Holding the data into the list
List<DataRow> strLot = ExcelDataSet.AsEnumerable().ToList();
con.Close();
//string lots = "";
//seperating the each lot with a comma separator
for (int i = 0; i < strLot.Count; i++)
{
totLots += ExcelDataSet.Rows[i].ItemArray.GetValue(0).ToString() + ",";
}
//Removing the last comma separator
totLots = totLots.Remove(totLots.Length - 1);
You can use the LIKE operator
WHERE <Column> LIKE '\**'
Also, depending on your data source, the wildcard '*' could be replaced with '%' and 'LIKE' keyword could be replaced with 'ALIKE'
with '%' the search text will become '*%' instead of '\**'
Edit: Code below checked with .xls and .xlsx files
OleDbCommand ExcelCommand = new OleDbCommand(#"SELECT LOT FROM [" + getExcelSheetName + #"] WHERE LOT LIKE '*%'", con);
Change your command text to the following...
#"SELECT [LOT] FROM [" + getExcelSheetName + #"] WHERE [LOT] LIKE '\*%')"
This should preform a simple pattern match like a SQL script and look for any member of the column starting with an asterisk and containing anything at all after that.

Reading Excel-file using Oledb - treating content of excel file as Text only

I am using C# and OleDb to read data from an excel 2007 file.
Connection string I am using is:
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended Properties="Excel 12.0 Xml;HDR=YES;IMEX=1";
Following is the code to read excel:
private OleDbConnection con = null;
private OleDbCommand cmd = null;
private OleDbDataReader dr = null;
private OleDbDataAdapter adap = null;
private DataTable dt = null;
private DataSet ds = null;
private string query;
private string conStr;
public MainWindow()
{
this.InitializeComponent();
this.query = "SELECT * FROM [Sheet1$]";
this.conStr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=C:\\Users\\301591\\Desktop\\Fame.xlsx;Extended Properties=\"Excel 12.0 Xml;HDR=YES;IMEX=1;TypeGuessRows=0;ImportMixedTypes=Text\"";
}
private void btnImport_Click(object sender, RoutedEventArgs e)
{
this.ImportingDataSetWay();
}
private void ImportingDataSetWay()
{
con = new OleDbConnection(conStr);
cmd = new OleDbCommand(query, con);
adap = new OleDbDataAdapter(cmd);
ds = new DataSet();
adap.Fill(ds);
this.grImport.ItemsSource = ds.Tables[0].DefaultView;
}
Here grImport is my WPF Data-Grid and I am using auto-generated columns.
How can I make sure the content stored in Excel will always be read as a string.
I am not allowed to modify any of the registry values to achieve this. Is there any better way to read excel. Please guide me. If you need any other information do let me know.
Regards,
Priyank
Could you try oledb provider connection string as follow.
HDR=NO means oledb will read all rows as data [NO HEADER]. So as your header columns are all text, it will treat all row data in all columns as text. After filling data into DataSet, you have to remove first row as it is not data.
Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\myFolder\myExcel2007file.xlsx;Extended Properties=\"Excel 12.0;IMEX=1;HDR=NO;TypeGuessRows=0;ImportMixedTypes=Text\"";
One fix we found, is to ensure that the first row contains a header.
i.e. make sure that your column names are in the first row. If that's possible.
Then in your code, you have to programmatically ignore the first row, while
at the same time scarfing your column names from it, if need be.
Use this in your connection string.
IMEX=1;HDR=NO;
I'm not sure of this
TypeGuessRows=0;ImportMixedTypes=Text
I had similar issue.. i resolved it by splitting the connectionstring as mentioned in following string. Please note that after extended properties.. there is (char)34 to surround IMEX=1 addition to the string. without surrounding with (char)34, it will give error "cant find ISAM". Hope this resolves your issue for ACE provider also
strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=" + Server.MapPath("UploadedExcel/" + FileName + ".xls") +
";Extended Properties=" +
(char)34 + "Excel 8.0;IMEX=1;" + (char)34;

C# VS2005 Syntax error (missing operator) in query expression

I am using VS2005 C# and SQL Server 2005. I am currently doing an import for a .CSV excel file data into my SQL Server database.
I am having some error, which I assume is related to my sql statement. Below is my code:
protected void Button1_Click(object sender, EventArgs e)
{
if (FileUpload1.HasFile)
{
// Get the name of the Excel spreadsheet to upload.
string strFileName = Server.HtmlEncode(FileUpload1.FileName);
// Get the extension of the Excel spreadsheet.
string strExtension = Path.GetExtension(strFileName);
// Validate the file extension.
if (strExtension != ".xls" && strExtension != ".xlsx" && strExtension != ".csv" && strExtension != ".csv")
{
Response.Write("<script>alert('Failed to import DEM Conflicting Role Datasheet. Cause: Invalid Excel file.');</script>");
return;
}
// Generate the file name to save.
string dir = #"C:\Documents and Settings\rhlim\My Documents\Visual Studio 2005\WebSites\SoD\UploadFiles\";
string mycsv = DateTime.Now.ToString("yyyyMMddHHmmss") + strExtension;
// Save the Excel spreadsheet on server.
FileUpload1.SaveAs(dir+mycsv);
// Create Connection to Excel Workbook
string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + dir + ";Extended Properties=Text;";
using (OleDbConnection ExcelConnection = new OleDbConnection(connStr))
{
OleDbCommand ExcelCommand = new OleDbCommand("SELECT [TABLES] FROM" + mycsv, ExcelConnection);
OleDbDataAdapter ExcelAdapter = new OleDbDataAdapter(ExcelCommand);
ExcelConnection.Open();
using (DbDataReader dr = ExcelCommand.ExecuteReader())
{
// SQL Server Connection String
string sqlConnectionString = "Data Source=<IP>;Initial Catalog=<DB>;User ID=<UID>;Password=<PW>";
// Bulk Copy to SQL Server
using (SqlBulkCopy bulkCopy =
new SqlBulkCopy(sqlConnectionString))
{
bulkCopy.DestinationTableName = "DEMUserRoles";
bulkCopy.WriteToServer(dr);
Response.Write("<script>alert('DEM User Data imported');</script>");
}
}
}
}
else Response.Write("<script>alert('Failed to import DEM User Roles Data. Cause: No file found.');</script>");
}
I am getting the error
"Syntax error (missing operator) in query expression '[Description] FROM20111109164041.csv'."
while executing using (DbDataReader dr = ExcelCommand.ExecuteReader()). Description is the last column in my database.
Anyone know what is wrong with my code? Thank You
You need a space between FROM and the csv file! :)
OleDbCommand ExcelCommand = new OleDbCommand("SELECT [TABLES] FROM " + mycsv, ExcelConnection);
That's why I always use the string.Format method, you see much better how the final string will look:
OleDbCommand ExcelCommand = new OleDbCommand(string.Format("SELECT [TABLES] FROM {0}",mycsv), ExcelConnection);
Seems like you need to place a blank between FROM and your CSV-File:
'[Description] FROM 20111109164041.csv'
If you are adding a string you should place it between single quotes
OleDbDataAdapter da = new OleDbDataAdapter("select * , '" + tempUid + "' as [UID] from [" + sheet1 + "]", conn);

Categories

Resources