I have been attempting to query an excel file from C# using an OLEDB connection. There are no runtime errors when the program runs, but it returns no results. I have tried it with different excel files but have gotten a similar result.
edit: The excel file is located in the project directory. If I remove the excel file from the current location the program will get a file not found exception.
private void btnRun_Click(object sender, EventArgs e)
{
string strFileName = "playerData.xls";
string connStr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=" + strFileName + ";Extended Properties=" + "\"Excel 8.0;HDR=YES\"";
OleDbConnection conn = new OleDbConnection(connStr);
conn.Open();
OleDbCommand cmd = conn.CreateCommand();
cmd.CommandType = CommandType.Text;
cmd.CommandText = "SELECT * FROM [Sheet1$]";
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
dgsResults.DataSource = ds;
conn.Close();
}
Does anyone know why this returns no results?
Thanks,
You are using strFileName in the connStr yet you have not provided the path with it.
Should be along the lines of:
string strFileName = #"c:\excel location\playerData.xls";
Apparently the specific data table has to be referenced in the data binding process. Adding the following line after the fill() method has solved the issue.
da.Fill(ds);
dgsResults.DataSource = ds.Tables[0]; //this is the line to be added
Related
I am building an app to read measurement data (saved as .xls files on our network) from comparators throughout our facility via a Webform. When I query this group of files I only retrieve the headers. My code (pretty standard) will read any other Excel file I can find. I tried to remove a file from the network and save it locally, as well as rename and save it from office 2016. Note - these are .xls files and I can't change that.
** - I just discovered that there are named ranges with the same name as the file. The results I am getting are just the values in the named range and not the data from the workbook.
Here is an example of how they are named (autogenerated) "R87_1RCR0009654S_COIN"
If I rename or remove the named range this works fine.
Is there a way I can change my select statement to read these?
Here is a code sample, not sure there if there is a change I can make here to read these files.
private string Excel03ConString = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1}'";
private string Excel07ConString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties='Excel 8.0;HDR={1}'";
string conStr, sheetName;
conStr = string.Format(Excel03ConString, info.FullName, "YES");
string fullPathToExcel = info.FullName;
//Get the name of the First Sheet.
using (OleDbConnection con = new OleDbConnection(conStr))
{
using (OleDbCommand cmd = new OleDbCommand())
{
cmd.Connection = con;
con.Open();
DataTable dtExcelSchema = con.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
sheetName = dtExcelSchema.Rows[0]["TABLE_NAME"].ToString();
con.Close();
}
}
using (OleDbConnection con = new OleDbConnection(conStr))
{
using (OleDbCommand cmd = new OleDbCommand())
{
using (OleDbDataAdapter oda = new OleDbDataAdapter())
{
DataTable dt = new DataTable();
cmd.CommandText = "SELECT * From [" + sheetName + "]";
cmd.Connection = con;
con.Open();
oda.SelectCommand = cmd;
oda.Fill(dt);
con.Close();
}
}
}
I am displaying data from an Excel Spreadsheet through an ASP.net web form using C#. I would like to run an SQL query on the data, but am having trouble figuring out how to use a string in my query.
Here is the code I am running in my .aspx.cs file. I am also using a .aspx to display the data in a GridView.
protected void Page_Load(object sender, EventArgs e)
{
string sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Server.MapPath("ExcelCSTest.xls") + ";" + "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
OleDbConnection objConn = new OleDbConnection(sConnectionString);
objConn.Open();
string sSQL = "SELECT * FROM [Sheet1$A1:D14]";
OleDbCommand objCmdSelect = new OleDbCommand(sSQL, objConn);
OleDbDataAdapter objAdapter1 = new OleDbDataAdapter();
objAdapter1.SelectCommand = objCmdSelect;
DataSet objDataset1 = new DataSet();
objAdapter1.Fill(objDataset1, "XLData");
GridView1.DataSource = objDataset1.Tables[0].DefaultView;
GridView1.DataBind();
objConn.Close();
}
Ideally, I would like to add a WHERE clause to my string sSQL = "SELECT * FROM [Sheet1$A1:D14]"; in order to query the current month and display the row of said month from the Excel Spreadsheet.
I have rewritten your code for you, however, you should seriously consider sticking into some coding standards. Please don't end your variables with numbers and consider formatting your code then it's more readable. Also you need to surround your OleDbConnection() inside a using statement then it gets disposed properly.
Here is the formatted and reworked code
public partial class ExcelAdapter : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
String sConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + Server.MapPath("ExcelCSTest.xls") + ";" + "Extended Properties=\"Excel 8.0;HDR=Yes;IMEX=1\"";
using (OleDbConnection objConn = new OleDbConnection(sConnectionString))
{
objConn.Open();
var sSQL = "SELECT * FROM [Sheet1$A1:D14]";
OleDbCommand objCmdSelect = new OleDbCommand(sSQL, objConn);
objCmdSelect.CommandType = CommandType.Text;
DataSet objDataset = new DataSet();
OleDbDataAdapter objAdapter = new OleDbDataAdapter(objCmdSelect).Fill(objDataset);
objConn.Close();
}
}
}
I haven't had time to test this code but I am pretty sure it should be spot on. (I hope)
Further more have a look at this tutorial. It's an excellent source to give you an idea of how to do this job properly.
Import Excel File to DataSet
Where Clause
It's very easy to add the where clause to your SQL and even better you can parametrize it to make it more standard.
Your code should look something like
var sSQL = "SELECT * FROM [Sheet1$A1:D14] WHERE currentDate = ?";
cmd.Parameter.Add("#Param1", OleDbType.VarChar).Value = todaysDate;
For the full example of how the parametrization should be done have a look at OleDbCommand.Parameters Property and also for even more details on an example you can check my answer's example to this question Missing Required Parameter in Parameterized Query?
public void LoadExcel_Click(object sender, EventArgs e)
{
OpenFileDialog fileDLG = new OpenFileDialog();
fileDLG.Title = "Open Excel File";
fileDLG.Filter = "Excel Files|*.xls;*.xlsx";
fileDLG.InitialDirectory = #"C:\Users\...\Desktop\";
if (fileDLG.ShowDialog() == DialogResult.OK)
{
string filename = System.IO.Path.GetFileName(fileDLG.FileName);
string path = System.IO.Path.GetDirectoryName(fileDLG.FileName);
excelLocationTB.Text = #path + "\\" + filename;
string ExcelFile = #excelLocationTB.Text;
if (!File.Exists(ExcelFile))
MessageBox.Show(String.Format("File {0} does not Exist", ExcelFile));
OleDbConnection theConnection = new OleDbConnection("Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + ExcelFile + ";Extended Properties=Excel 12.0;");
theConnection.Open();
OleDbDataAdapter theDataAdapter = new OleDbDataAdapter("SELECT * FROM [Sheet1$]", theConnection);
DataSet DS = new DataSet();
theDataAdapter.Fill(DS, "ExcelInfo");
dataGridView1.DataSource = DS.Tables["ExcelInfo"];
formatDataGrid();
MessageBox.Show("Excel File Loaded");
toolStripProgressBar1.Value += 0;
}
}
Ok so I got this code off of Microsoft.
theDataAdapter.Fill(DS, "ExcelInfo");
This is the line that gave me the error.
Basically this code is supposed to use a dialog box to open the file and display it on the form. Whenever I opened an Excel file, it would give me this error. I even tried creating a blank excel file and it still gave me this.
Modified your code. added OleDbCommand to do the query selection. just try.
OleDbConnection theConnection = new OleDbConnection(#"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=D:\Projects\Demo\Demo.xls;Extended Properties=Excel 8.0;");
theConnection.Open();
OleDbCommand theCmd = new OleDbCommand("SELECT * FROM [Sheet1$]", theConnection);
OleDbDataAdapter theDataAdapter = new OleDbDataAdapter(theCmd);
DataSet DS = new DataSet();
theDataAdapter.Fill(DS);
theConnection.Close();
I have seen this error before and it might not have anything to do with your code. The code below works fine, but if you are getting your source that has blocked the file, make sure you right-click the file and go to properties and check unblock. This could be if you are downloading the file from some source etc. A good test is to just open the exported excel file and save it and try again. Or copy the contents into a new excel file.
Again the code below works fine, but when I tried to import without unblocking or going into the file and saving it I was getting the same error. The error message is deceiving.
string excelconString = string.Format(#"Provider=Microsoft.ACE.OLEDB.12.0;Data Source={0};Extended Properties=""Excel 12.0 Xml;HDR=YES;IMEX=1""", filePath);
string excelQuery = "select col1 from [Sheet1$]";
DataSet ds = new DataSet();
DataTable dt = new DataTable();
using (var excelConn = new OleDbConnection(excelconString))
{
excelConn.Open();
using (var oda = new OleDbDataAdapter(excelQuery, excelConn))
{
oda.Fill(ds);
dt = ds.Tables[0];
}
}
How can I get the data in a .dbf file using c#??
What I want to do is to read the data in each row (same column) to further process them.
Thanks.
You may create a connection string to dbf file, then using OleDb, you can populate a dataset, something like:
string constr = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=directoryPath;Extended Properties=dBASE IV;User ID=Admin;Password=;";
using (OleDbConnection con = new OleDbConnection(constr))
{
var sql = "select * from " + fileName;
OleDbCommand cmd = new OleDbCommand(sql, con);
con.Open();
DataSet ds = new DataSet(); ;
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds);
}
Later you can use the ds.Tables[0] for further processing.
You may also check this article Load a DBF into a DataTable
I found out the accepted answer didn't work for me, as the .dbf files I'm working with are nested in a hierarchy of directories that makes the paths rather long, which, sadly, cause the OleDbCommand object to throw.
I found a neat little library that only needs a file path to work. Here's a little sample adapted from the examples on its GitHub page:
var file = "C:\\Path\\To\\File.dbf";
using (var dbfDataReader = new DbfDataReader(file))
{
while (dbfDataReader.Read())
{
var foo = Convert.ToString(dbfDataReader["FOO"]);
var bar = Convert.ToInt32(dbfDataReader["BAR"]);
}
}
For 64 bit systems I used the Microsoft ACE OLEDB 12.0 data provider, for that provider to work you have to install Microsoft's Access Database Engine 2010
So it looks a lot like the accepted answer but with the provider changed:
string constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=c:\folder;Extended Properties=dBASE IV;User ID=Admin;";
using (OleDbConnection con = new OleDbConnection(constr))
{
var sql = "select * from " + fileName;
OleDbCommand cmd = new OleDbCommand(sql, con);
con.Open();
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(cmd);
da.Fill(ds);
}
I am using the following code to read my csv file:
public DataTable ParseCSV(string path)
{
if (!File.Exists(path))
return null;
string full = Path.GetFullPath(path);
string file = Path.GetFileName(full);
string dir = Path.GetDirectoryName(full);
//create the "database" connection string
string connString = "Provider=Microsoft.ACE.OLEDB.12.0;"
+ "Data Source=\"" + dir + "\\\";"
+ "Extended Properties=\"text;HDR=Yes;FMT=Delimited\"";
//create the database query
string query = "SELECT * FROM " + file;
//create a DataTable to hold the query results
DataTable dTable = new DataTable();
//create an OleDbDataAdapter to execute the query
OleDbDataAdapter dAdapter = new OleDbDataAdapter(query, connString);
//fill the DataTable
dAdapter.Fill(dTable);
dAdapter.Dispose();
return dTable;
}
But the above doesn't reads the alphanumeric value from the csv file. it reads only i either numeric or alpha.
Whats the fix i need to make to read the alphanumeric values? Please suggest.
I suggest you use A Fast CSV Reader which does not have this issue and is much more faster.
Remove IMEX=1 from the connection string. I don't think you need it for CSV files.
Try this OleDBAdapter Excel QA I posted via stack overflow.
I have not tried this out, but it sounds interesting! LinqToExcel
they say it can be used on .CSV files as well...
hi all this code is gets alphanumeric values also
using System.Data.OleDb;
string ConnectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;" + "Data Source=" + filepath + ";" + "Extended Properties="+(char)34+"Excel 8.0;IMEX=1;"+(char)34;
string CommandText = "select * from [Sheet1$]";
OleDbConnection myConnection = new OleDbConnection(ConnectionString);
myConnection.Open();
OleDbDataAdapter myAdapter = new OleDbDataAdapter(CommandText, myConnection);
ds = null;
ds = new DataSet();
myAdapter.Fill(ds);