I can use a query table:
var sheet = (_excel.ActiveSheet as Excel.Worksheet);
var rng = sheet.Range("A1");
var qt = sheet.QueryTables.Add("ODBC;...", rng, "SELECT * FROM myTable");
qt.Refresh();
and this will import the data correctly (e.g. dates actually display as dates etc...). But when I try and access the ListObject to apply a TableStyle I get an exception.
Now if I add a list object like:
var sheet = (_excel.ActiveSheet as Excel.Worksheet);
var qt = sheet.ListObjects.Add(
Excel.Enums.XlListObjectSourceType.xlSrcQuery,
"ODBC;...",
null,
Excel.Enums.XlYesNoGuess.xlNo,
rng,
"TableStyleMedium9").QueryTable;
qt.CommandType = Excel.Enums.XlCmdType.xlCmdSql;
qt.CommandText = "SELECT * FROM myTable";
qt.Refresh();
The the dates in the query display as decimal numbers and not dates...
I could just format the columns afterwards, but the problem is that I won't actually know the query that is being run as the user types this at runtime, so I would prefer to get Excel to do this.
So essentially, what I want, is to use the first bit of code and apply a TableStyle to it.
Can anyone help?
This doesn't do coloring, but it does organize the data into a datatable, and when you're debugging with breakpoints and mouse over the datatable after its been filled you can see all the data organized into columns. What you can then do with the datatable is bind it to a datagrid view on your win forms element.
I have this DataTable DataTable = new DataTable(); as a global field at the top.
OleDbConnection conn = new OleDbConnection();
//This is making a connection to the excel file, don't worry about this I think you did it differently.
conn.ConnectionString = #"Provider=Microsoft.ACE.OLEDB.12.0;" + "Data Source=" + stringFileName + ";" + "Extended Properties=\"Excel 12.0;HDR=Yes;\""; OleDbCommand cmd = new OleDbCommand
("SELECT * FROM [" + sheetFromTo + "]", conn);
DataSet dataSet1 = new DataSet();
OleDbDataAdapter dataAdapter = new OleDbDataAdapter(cmd);
try
{
conn.Open();//opens connection
dataSet1.Clear();//empties, incase they refill it later
dataAdapter.SelectCommand = cmd;//calls the cmd up above
dataAdapter.Fill(dataSet1);//fills the dataset
dataGridView1.DataSource = dataSet1.Tables[0];//puts the dataset in the dataGridview
//important** creates a datatable from the dataset, most of our work with the server is with this datatable
DataTable dataTable = dataSet1.Tables[0];
DataTable = dataTable;
}
catch (Exception ex)
{
}
finally
{
conn.Close();
}
Related
I need to fetch a row value from an excel sheet in data grid view in winform.
I’m able to display the entire excel sheet in the datagridview. But, I need to display particular rows in the grid based on a current date condition.
public DataTable ReadExcel2(string fileName, string fileExt)
{
string connectionstring ;
DataTable dtexcel2 = new DataTable();
connectionstring = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=YES';";
OleDbConnection connection = new OleDbConnection(connectionstring);
OleDbCommand oconn = new OleDbCommand("Select * From [POSFailures$] WHERE Date=#date");
oconn.Connection = connection;
try
{
oconn.Parameters.AddWithValue("#date", DateTime.Now.ToString("MM/dd/yyyy"));
connection.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
sda.Fill(dtexcel2);
connection.Close();
}
catch (Exception)
{
}
return dtexcel2;
}
Thanking you in advance
What seems to be happening here is that the Date parameter is not being honored, as you are getting back all of the rows. So, I used Google to figure out how to properly add parameters when using OleDbConnection. I found this:
The OLE DB .NET Provider does not support named parameters for passing parameters to an SQL statement
Source: https://learn.microsoft.com/en-us/dotnet/api/system.data.oledb.oledbcommand.parameters?redirectedfrom=MSDN&view=netframework-4.8#System_Data_OleDb_OleDbCommand_Parameters
Using the example on that page, try changing your code to this:
string connectionstring;
DataTable dtexcel2 = new DataTable();
connectionstring = #"Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties='Excel 12.0;HDR=YES';";
OleDbConnection connection = new OleDbConnection(connectionstring);
OleDbCommand command = new OleDbCommand("Select * From [POSFailures$] WHERE Date = ?");
command.Parameters.Add(new OleDbParameter(DateTime.Now.ToString("MM/dd/yyyy"), OleDbType.Date));
command.Connection = connection;
try
{
connection.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(command);
sda.Fill(dtexcel2);
connection.Close();
}
catch (Exception)
{
}
Please note that i've not tested this, so I can't promise it will work. But, the main point is... the answer is out there! You just need to go looking for it.
Hello i need to "merge" 2 DataTables in one datagridview and i can't handle it. So far i have sth like this code below and now i want to place another datatable(it have the same number of columns) just below this without any separation(just like adding new rows). For example the code below returns 3 rows so i want my data from another source to appear starting in row 4, how can i do this ? Anyone can help ?
private void button1_Click(object sender, EventArgs e)
{
String name = "Items";
String constr = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" +
"C:\\test.xlsx" +
";Extended Properties='Excel 8.0;HDR=YES;';";
OleDbConnection con = new OleDbConnection(constr);
OleDbCommand oconn = new OleDbCommand("Select * From [" + name + "$]", con);
con.Open();
OleDbDataAdapter sda = new OleDbDataAdapter(oconn);
DataTable data = new DataTable();
sda.Fill(data);
dataGridView1.DataSource = data;
}
Try this..
Add a new DataTable for another datasource and then add new datarow to first datatable (data)
Then add the columns and relevant data to it.
Do all this after filling first datatable from db.
take reference from this
http://www.codeproject.com/Questions/670856/how-to-add-new-row-and-new-values-in-gridview-in-a
My excel simulation needs to be imported into C#, after which the table needs to be able to be refreshed. The simulation revolves around randomly generated numbers. The random numbers are the only columns that change, since I'm doing that manually. The surrounding columns should update with the random numbers. I have tried various things but no luck so far.
Also, as the code is now, the
adp.Update(excelDataSet);
command invokes the error "Update requires a valid UpdateCommand when passed DataRow collection with modified rows." The table is only loaded into the gridview at all when it is commented out.
Here is my code atm. Thanks in advance.
string fileName = #"C:\simulation.xlsx";
string connectionString = "Provider=Microsoft.ACE.OLEDB.12.0;Data Source=" + fileName + ";Extended Properties=\"Excel 12.0;HDR=Yes;READONLY=FALSE\"";
OleDbConnection con = new System.Data.OleDb.OleDbConnection(connectionString);
con.Open();
OleDbCommand selectCommand = new OleDbCommand("select * from [SHEET1$]", con);
OleDbDataAdapter adp = new System.Data.OleDb.OleDbDataAdapter();
adp.SelectCommand = selectCommand;
DataSet excelDataSet = new DataSet();
adp.Fill(excelDataSet);
for (int i = 0; i < 29; i++)
{
excelDataSet.Tables[0].Rows[i][1] = Math.Round(r.NextDouble(), 2);
excelDataSet.Tables[0].Rows[i][6] = Math.Round(r.NextDouble(), 2);
excelDataSet.Tables[0].Rows[i][8] = Math.Round(r.NextDouble(), 2);
}
adp.Update(excelDataSet);
gridview.DataSource = excelDataSet.Tables[0];
con.Close();
Add a line that build a OleDbCommandBuilder
....
OleDbDataAdapter adp = new System.Data.OleDb.OleDbDataAdapter();
adp.SelectCommand = selectCommand;
OleDbCommandBuilder cb = new OleDbCommandBuilder(adp);
adp.UpdateCommand = cb.GetUpdateCommand();
....
This will create the UpdateCommand in the OleDbDataAdapter for you, (can be used also for the InsertCommand and DeleteCommand)
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
How can i select specific columns from excel sheet in c#?
string strConn = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=|DataDirectory|2.xls;Extended Properties='Excel 8.0;HDR=no;'";
string query = "SELECT * FROM [Sheet1$]";
DataSet excelDataSet = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter(query, strConn);
da.Fill(excelDataSet);
GridView1.DataSource = excelDataSet;
GridView1.DataBind();
GridView1.HeaderRow.Cells[0].Text = "CheckNumber";
I have this code to read an Excel Spreadsheet being loaded from a website and being displayed in a gridview. I would like to simply just read column A on the spreadsheet. I think I should be able to change this string query = "SELECT * FROM [Sheet1$]"; but all my efforts have been futile. Can someone point me in the right direction, or is there a better way to do this.
it looks like the way to do this is simply
string sql = "SELECT F1, F2, F3, F4, F5 FROM [sheet1$];
Thanks for the comments everyone.
I believe your problem lies in the fact that a spreadsheet is not a database. A spreadsheet is under no obligation to be rectangular or have cells of the same type. So saying you want a column ASSUMES that that column exists for all rows and is of the same type. So before you issue SQL against it you need to convert to a vector of the same type.
Here is what I use to read an Excel Spreadsheet and return it as a DataTable and if you focus in on the following section where I am able to query all of the workbooks in the Spreadsheet by looping through the dtSchema DataTable object to find the names of the different worksheets:
public static DataTable GetExcelData(string connectionString)
{
string sql = string.Empty;
using (OleDbConnection cn = new OleDbConnection(connectionString))
{
using (OleDbDataAdapter adapter = new OleDbDataAdapter())
{
DataTable dt = new DataTable();
using (OleDbCommand command = cn.CreateCommand())
{
cn.Open();
DataTable dtSchema = cn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables, new object[] { null, null, null, "TABLE" });
foreach (DataRow dr in dtSchema.Rows)
{
//Will Loop through the name of each Worksheet
Console.WriteLine(dr["Table_Name"]);
}
string firstSheetName = dtSchema.Rows[0].Field<string>("TABLE_NAME");
sql = "SELECT * FROM [" + firstSheetName + "]";
command.CommandText = sql;
adapter.SelectCommand = command;
adapter.Fill(dt);
if (dt.Rows.Count == 0)
{
OleDbDataReader reader = command.ExecuteReader();
dt.Load(reader);
}
cn.Close();
return dt;
}
}
}
}
So my code looks like this currently, which is all fine and good
String q = "SELECT * FROM "+"test.csv";
try
{
OleDbConnection cn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\;Extended Properties=\"Text;HDR=No;FMT=Delimited\"");
OleDbDataAdapter da = new OleDbDataAdapter();
DataSet ds = new DataSet();
OleDbCommand cd = new OleDbCommand(q, cn);
cn.Open();
da.SelectCommand = cd;
ds.Clear();
da.Fill(ds, "CSV");
dataGridView1.DataSource = ds.Tables[0];
cn.Close();
}
catch (Exception ex)
{
MessageBox.Show("There was an issue: " + ex.Message);
}
However, I would like to take the first row in my CSV and use that as the field names, so I can do something like
"select a.ID, a.SOMETHING_ELSE from test.csv a"
where the CSV looks something like
ID,SOMETHING_ELSE,DONT_WANT_THIS
1,blah,I don't want to see this
Yet, from what I see, about all examples on the web show nothing other than select *, and I would like my datagrid to show the headers as the field names selected, instead of F1, F2....
Is this implemented anywhere?
Change your connection string to include HDR=Yes (instead of HDR=No):
OleDbConnection cn = new OleDbConnection("Provider=Microsoft.Jet.OLEDB.4.0; Data Source=C:\\;Extended Properties=\"Text;HDR=Yes;FMT=Delimited\"");
For OleDB, the HDR property in the connection string indicates whether or not the first row contains the column names.