Reading Excel in .NET, how to get specific rows? - c#

I have got the following code from here to read an Excel file using C# .NET:
string connectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Book1.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
DbProviderFactory factory = DbProviderFactories.GetFactory("System.Data.OleDb");
DbCommand command = connection.CreateCommand()
command.CommandText = "SELECT City,State FROM [Cities$]";
I want to select only 10 rows starting from the 4th row, how can I do that?

I'm no Excel querying expert, but this certainly works. Use TOP to limit the query to 13 rows. The first row is the header with column names so it may not count. Obviously change if I misunderstand. Then, keep track of a row ID and do stuff to rows on or after 4.
Hope this helps!
string connectionString = #"Provider=Microsoft.Jet.OLEDB.4.0;Data Source=Book1.xls;Extended Properties=""Excel 8.0;HDR=YES;""";
using (System.Data.OleDb.OleDbConnection conn = new System.Data.OleDb.OleDbConnection(connectionString)) {
System.Data.OleDb.OleDbCommand cmd = new System.Data.OleDb.OleDbCommand();
cmd.Connection = conn;
cmd.CommandText = "SELECT top 13 City,State FROM [Cities$]";
conn.Open();
System.Data.IDataReader dr = cmd.ExecuteReader();
int row = 2;
while (dr.Read()) {
if (row++ >= 4) {
// do stuff
Console.WriteLine("{0}, {1}", dr[0], dr[1]);
}
}
}

Related

C# Query MS-Access Table and place read values from column in a text box

Below is a snapshot of my code. I am trying to access the only column in the customer table and place the values into a textbox on the form. I keep getting the error with my code "InvalidOperationException was unhandled" at the line declaring dr as a OleDbDataReader object.
What do I have wrong with the below code that would be giving me this error?
Should I do a list to pick out the text I want from the database?
How can I return the column values from access into a list in C# so that I can search the list for a particular value?
string strsql = "Select * from Customer";
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = strsql;
conn.Open();
OleDbDataReader dr = cmd.ExecuteReader();
while(dr.Read())
{
textBox1.Text += dr["Customer"].ToString();
}
conn.Close();
A command carries the info to be executed, a connection carries the info to reach the database server. The two objects should be linked together to produce any result. You miss that line
OleDbCommand cmd = new OleDbCommand();
cmd.CommandText = strsql;
cmd.Connection = conn; // <= here
conn.Open();
Remember also that disposable objects like a command, a reader and a connection should be disposed immediately after usage. For this pattern exists the using statement
So you should write
string cmdText = "Select * from Customer";
using(OleDbConnection conn = new OleDbConnection(.....constring...))
using(OleDbCommand cmd = new OleDbCommand(cmdText, conn))
{
conn.Open();
using(OleDbDataReader reader = cmd.ExecuteReader())
{
while(reader.Read())
.....
}
}
Here is some sample code.
try
{
using (OleDbConnection myConnection = new OleDbConnection())//make use of the using statement
{
myConnection.ConnectionString = myConnectionString;
myConnection.Open();//Open your connection
OleDbCommand cmdNotReturned = myConnection.CreateCommand();//Create a command
cmdNotReturned.CommandText = "someQuery";
OleDbDataReader readerNotReturned = cmdNotReturned.ExecuteReader(CommandBehavior.CloseConnection);
// close conn after complete
// Load the result into a DataTable
if (readerNotReturned != null) someDataTable.Load(readerNotReturned);
}
}
After that you have a Datatable containing your data. Ofcourse you can afterwards search for records in the Datatable any way you like.

How to Insert Rows to Table Object Inside an Excel Sheet?

I have difficulties trying to insert rows into an existing table object. Here is my code snippet:
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + #"C:\myExcelFile.xlsx" + ";Extended Properties=\"Excel 12.0;ReadOnly=False;HDR=Yes;\"";
using (OleDbConnection conn = new OleDbConnection(connectionString))
{
conn.Open();
OleDbCommand cmd = new OleDbCommand();
cmd.Connection = conn;
string insertQuery = String.Format("Insert into [{0}$] (ID, Title,NTV_DB, Type ) values(7959, 8,'e','Type1')", TabDisplayName);
cmd.CommandText = insertQuery;
cmd.ExecuteNonQuery();
cmd = null;
conn.Close();
}
As a result I get my rows inserted below a ready-made table object:
I've also tried inserting data inside a table object like so:
string insertQuery = String.Format("Insert into [{0}$].[MyTable] (ID, Title,NTV_DB, Type ) values(7959, 8,'e','Type1')", TabDisplayName);
But I get an error:
The Microsoft Access database engine could not find the object 'MyTable'. Make sure the object exists and that you spell its name and the path name correctly. If 'MyTable' is not a local object, check your network connection or contact the server administrator.
As you can see, table with a name MyTable does exist. I would be very grateful if someone can shed some light on this mystery.
If you are using the Microsoft.ACE.OLEDB provider, then be aware that it doesn't support a named range. You need to provide the name of the sheet [Sheet1$] or the name of the sheet followed by the range [Sheet1$A1:P7928].
If the range is not provided, it will then define the table as the used range, which may contains empty rows.
One way to deal with empty rows would be to delete them, but the driver doesn't support the DELETE operation.
Another way is to first count the number of rows with a non empty Id and then use the result to define the range of the table for the INSERT statement:
using (OleDbConnection conn = new OleDbConnection(connectionString)) {
conn.Open();
string SheetName = "Sheet1";
string TableRange = "A1:P{0}";
// count the number of non empty rows
using (var cmd1 = new OleDbCommand(null, conn)) {
cmd1.CommandText = String.Format(
"SELECT COUNT(*) FROM [{0}$] WHERE ID IS NOT NULL;"
, SheetName);
TableRange = string.Format(TableRange, (int)cmd1.ExecuteScalar() + 1);
}
// insert a new record
using (var cmd2 = new OleDbCommand(null, conn)) {
cmd2.CommandText = String.Format(
"INSERT INTO [{0}${1}] (ID, Title, NTV_DB, Type) VALUES(7959, 8,'e','Type1');"
, SheetName, TableRange);
cmd2.ExecuteNonQuery();
}
}
If you execute this code:
var contents = new DataTable();
using (OleDbDataAdapter adapter = new OleDbDataAdapter(string.Format("Select * From [{0}$]", TabDisplayName), conn))
{
adapter.Fill(contents);
}
Console.WriteLine(contents.Rows.Count);//7938
you will see 7938 (last row number on your screenshot). And when you insert new row, it inserted at 7939 position. Empty content in (7929, 7930, ...) rows are ignored, because excel knows that last number is 7938.
Solutions:
You must delete all rows after 7928 in excel file.
You must insert on specific position.
I'm not sure Access C# works the same as Excel, but this worked on a spreadsheet for me. Maybe it could help you?
Table3.ListRows[1].Range.Insert(Excel.XlInsertShiftDirection.xlShiftDown);
Try this
private void GetExcelSheets(string FilePath, string Extension, string isHDR)
{
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;
}
//Get the Sheets in Excel WorkBoo
conStr = String.Format(conStr, FilePath, isHDR);
OleDbConnection connExcel = new OleDbConnection(conStr);
OleDbCommand cmdExcel = new OleDbCommand();
OleDbDataAdapter oda = new OleDbDataAdapter();
cmdExcel.Connection = connExcel;
connExcel.Open();
//Bind the Sheets to DropDownList
ddlSheets.Items.Clear();
ddlSheets.Items.Add(new ListItem("--Select Sheet--", ""));
ddlSheets.DataSource=connExcel
.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, null);
ddlSheets.DataTextField = "TABLE_NAME";
ddlSheets.DataValueField = "TABLE_NAME";
ddlSheets.DataBind();
connExcel.Close();
txtTable.Text = "";
lblFileName.Text = Path.GetFileName(FilePath);
Panel2.Visible = true;
Panel1.Visible = false;
}

Truncate DataGridView fields so it doesnt exceed 10 characters?

So I have a form that when it is opened, loads selected information from a database. However, I want to truncate the Date column, so instead of showing how
'DD/MM/YYYY HH:mm:ss a.m/p.m'
I want it to only show
'DD/MM/YYYY'
I'm using SQL Server Management Studio for my database, and was under the impression that a Date type in that didn't record the time field anyway.
My code for populating the DGV:
SqlConnection con = new SqlConnection("Data Source=localhost\\SQLEXPRESS;Initial Catalog=FarmersMarket;Integrated Security=True");
SqlCommand cmd = new SqlCommand();
SqlDataReader dr;
cmd.Connection = con;
con.Open();
cmd.CommandText = "Select EventID, EventDate, Location from Events";
dr = cmd.ExecuteReader();
if (dr.HasRows)
{
while (dr.Read())
{
int n = dgvEvents.Rows.Add();
dgvEvents.Rows[n].Cells[0].Value = dr[0].ToString();
dgvEvents.Rows[n].Cells[1].Value = dr[1].ToString();
dgvEvents.Rows[n].Cells[2].Value = dr[2].ToString();
}
}
con.Close();
I think this can be your solution but not a good solution
dgvEvents.Rows[n].Cells[1].Value = dr[1].TrimEnd(' ').ToString();

How to populate data from SQL Server database columns to textboxes

I want to populate data from a SQL Server database from many columns to many textboxes .. I have a code to populate just one box .. can someone edit my code... I want to pull data and show it in Name, Address, Telephone No and Date ... plz help .. this code works for only one textbox..
Thanks in advance
SqlConnection Conn = new SqlConnection(#"Data Source=rex;Initial Catalog=PersonalDetails;Integrated Security=True");
SqlCommand Comm1 = new SqlCommand("Select * From PersonalUsers ", Conn);
Conn.Open();
SqlDataReader DR1 = Comm1.ExecuteReader();
if (DR1.Read())
{
Name.Text = DR1.GetValue(0).ToString();
}
while (DR1.Read())
{
if(DR1.GetName() == "YourSQLColumnName")
{
YourTextBox.Text = (string) DR1["YourSQLColumnName"];
}
// Your Other textboxes and columns which you want to match should follow as this template
}
SqlCommand cmd = new System.Data.SqlClient.SqlCommand(sql, _conn);
SqlDataReader rdr = cmd.ExecuteReader();
System.Data.DataTable tbl = new System.Data.DataTable("Results");
tbl.Load(rdr);
if (tbl.Rows.Count > 0)
Name.Text = tbl.Rows[0]["column_name"].ToString();
string cs=System.Configuration.ConfigurationManager.ConnectionString["DBCS"].ConnectionString;
using(OracleConnection con=new OracleConnection(cs))
{
sql="select empname from Emp where empno='"+empno+"'";
OracleCommand cmd = new System.Data.OracleClient.OracleCommand(sql,con);
con.Open();
OracleDataReader rdr = cmd.ExecuteReader();
if(rdr.Read())
{
EmpName.Text=Convert.ToString(rd["empname"]);
}
}
I assume that you would like to take care of both more rows and more columns.
Try to specify the columns. It works without, but the performance is better if you do so.
I assume you have a class called PersonalUser with the specifed properties.
It is also nice to have it in an sorted order, so I added that
public List<PersonalUser> FetchMyData()
{
SqlConnection Conn = new SqlConnection(#"Data Source=rex;Initial Catalog=PersonalDetails;Integrated Security=True");
SqlCommand Comm1 = new SqlCommand("Select Name, Address, TelephoneNo,Date From PersonalUsers order by Name", Conn);
Conn.Open();
SqlDataReader DR1 = Comm1.ExecuteReader();
var result = new List<PersonalUser>();
while (DR1.Read())
{
result.Add(new PersonalUser {
Name = DR1.GetString(0);
Address= DR1.GetString(1);
TelephoneNo = DR1.GetString(2);
Date = DR1.GetString(3)
}
);
}
return result;
}
I would also, if the need is getting much complex than this, conidering using Entity Framwork..

Reading from an Access Database c#

I'm trying to read from an access database and put the results in a listbox. Here is the code I have, it keeps telling me that "No data exists for the row/column. I have data entered in a Column named "GroupName" and have data in a column named "RandomNumber" in the table "GroupNames"
db = new OleDbConnection();
db.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;Data source=" + fileName;
db.Open();
string sql = "SELECT * FROM GroupNames ORDER BY RandomNumber ASC";
cmd = new OleDbCommand(sql, db);
rdr = cmd.ExecuteReader();
lblist.Text = (string)rdr["GroupName"];
Try this:
lblist.Items.Clear();
rdr = cmd.ExecuteReader();
while (rdr.Read())
{
//lblist.Text += (string)rdr["GroupName"];
lblist.Items.Add((string)rdr["GroupName"]);
}
You need to move the reader to the first row by calling rdr.Read().
If there is no row to move to, Read() will return false.

Categories