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)
Related
i am developing a C# web application which need to process an excel sheet containing names of places and deposits and withdrawals which will be sorted and displayed in datagridview and later it will be saved in a microsoft access database.
I am able to retrieve officenames, sort and display the contents in datagridview
Click to watch the output of datagrid view on the left
But the problem is my excel file contains both strings and numbers in its sheet.
Excel file screenshot 1
Excel file screen shot 2
As you can see even though the excel file contains numbers, the datagridview on the right doesn't display excel cells with number values. Please watch the gridview on the right in the first image for the reference.
The code i am using is:
using (OleDbConnection con = new OleDbConnection(conStr))
{
using (OleDbCommand cmd = new OleDbCommand())
{
using (OleDbDataAdapter oda = new OleDbDataAdapter())
{
System.Data.DataTable dt = new System.Data.DataTable();
cmd.CommandText = "SELECT * From [" + sheetName + "]";
//new code to displayi contents to temp datagrid
System.Data.OleDb.OleDbConnection MyConnection;
System.Data.DataSet DtSet;
System.Data.OleDb.OleDbDataAdapter MyCommand;
MyConnection = new System.Data.OleDb.OleDbConnection(#"provider=Microsoft.Jet.OLEDB.4.0;Data Source='C:\Users\acer\Documents\Visual Studio 2012\Projects\SBCO consolidation Reporter\SBCO consolidation Reporter\Files\RD1.xls';Extended Properties=Excel 8.0;");
MyCommand = new System.Data.OleDb.OleDbDataAdapter("SELECT * From [" + sheetName + "]", MyConnection);
MyCommand.TableMappings.Add("Table", "Net-informations.com");
DtSet = new System.Data.DataSet();
MyCommand.Fill(DtSet);
dataGridView2.DataSource = DtSet.Tables[0];
MyConnection.Close();
//new code end
cmd.Connection = con;
con.Open();
oda.SelectCommand = cmd;
oda.Fill(dt);
con.Close();
//Populate DataGridView.
System.Data.DataTable tempDT = new System.Data.DataTable();
tempDT = dt.DefaultView.ToTable(true, "F2");
foreach (DataRow row in tempDT.AsEnumerable().Take(7).ToList())
{
row.Delete();
}
int count = tempDT.Rows.Count;
tempDT.Rows[count - 1].Delete();
tempDT.Rows[count - 2].Delete();
tempDT.Rows[count - 4].Delete();
DataView dv = tempDT.DefaultView;
dv.Sort = "F2 asc";
System.Data.DataTable sortedDT = dv.ToTable();
sortedDT.Columns[0].ColumnName = "Office Name";
//sortedDT.Columns[1].ColumnName = "Finacle Dep";
sortedDT.Columns.Add("Profit Center Code", typeof(System.Int32));
sortedDT.Columns.Add("Finacle Dep", typeof(System.Int32));
sortedDT.Columns.Add("Finacle Withdrawal", typeof(System.Int32));
tempDT.AcceptChanges();
dataGridView1.DataSource = sortedDT;
dataGridView1.Columns["Office Name"].ReadOnly = true;
con.Close();
}
}
}
So where am i doing it wrong. Please help!
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();
}
How can I save a DataTable to a file. accdb (Access) existing one? I've used the following code and it does not work:
using (OleDbConnection oledbConnection = new OleDbConnection(connection))
{
oledbConnection.Open();
string query = "SELECT * FROM Student";
using (OleDbCommand oledbCommand = new OleDbCommand(query, oledbConnection))
{
using (OleDbDataAdapter oledbDataAdapter = new OleDbDataAdapter(oledbCommand))
{
using (OleDbCommandBuilder oledbCommandBuilder = new OleDbCommandBuilder(oledbDataAdapter))
{
oledbDataAdapter.DeleteCommand = oledbCommandBuilder.GetDeleteCommand(true);
oledbDataAdapter.InsertCommand = oledbCommandBuilder.GetInsertCommand(true);
oledbDataAdapter.UpdateCommand = oledbCommandBuilder.GetUpdateCommand(true);
oledbDataAdapter.Update(dataTable);
}
}
}
oledbConnection.Close();
}
The variable dataTable is initialized with the original contents of the file, then it was modified by adding a row and now I have to update the table in the database.
I tried using the following code, but that does not work :(
OleDbDataAdapter da = new OleDbDataAdapter("SELECT * FROM Student", connection);
OleDbCommandBuilder cmdBuilder = new OleDbCommandBuilder(da);
da.InsertCommand = cmdBuilder.GetInsertCommand(true);
// create and insert row in the DataTable
da.Update(dataTable);
Assuming that you have made some changes in the datatable, then you could pass the generated update/insert/delete command to the adapter in this way
oledbDataAdapter.DeleteCommand = oledbCommandBuilder.GetDeleteCommand();
oledbDataAdapter.InsertCommand = oledbCommandBuilder.GetInsertCommand();
oledbDataAdapter.UpdateCommand = oledbCommandBuilder.GetUpdateCommand();
oledbDataAdapter.Update(datatable);
Now the adapter knows how to update your table
Hello well i try to import a Excel document into my DataGridView in C#.
So far it worked but there is a Column with Data in it i need to 'sort'.
If this was simple i would do "WHERE test > 0" in the OleDbDataAdapter query.
But.. The name of the Column is changing with each document and i need to use it often. So far i got this :
private void button1_Click(object sender, EventArgs e)
{
String strConn = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=C:\\Users\\Test\\Desktop\\Test.xls;" +
"Extended Properties=Excel 8.0;";
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Test$]", strConn);
da.Fill(ds);
dataGridView1.DataSource = ds.Tables[0].DefaultView;
}
In the select i need to put a line witch state that the first 3 letters of the column is the same but the number that follow are not. Like:
QTA 12345,
QTA 13213,
QTA 92818.
Something like:
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Test$] WHERE [testColumn] > 0", strConn);
But then with the same first 3 letters and the last numbers who are random.
Can someone help me please?
I've tried some code and it works fine for me. Have a try:
OleDbConnection oleDbConnection = new OleDbConnection(
"Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=D:\\Users\\name\\Desktop\\test.xls;" +
"Extended Properties='Excel 8.0;HDR=Yes;IMEX=1'");
oleDbConnection.Open();
//Get columns
DataTable dtColumns = oleDbConnection.GetSchema("Columns", new string[] { null, null, "Tabelle1$", null });
List<string> columns = new List<string>();
foreach (DataRow dr in dtColumns.Rows)
columns.Add(dr[3].ToString());
string colName = columns.Find(item => item.Substring(0,3) == "QTA");
DataSet ds = new DataSet();
OleDbDataAdapter da = new OleDbDataAdapter
("SELECT * FROM [Tabelle1$] WHERE [" + colName + "] > 0", oleDbConnection);
da.Fill(ds);
dataGrid1.ItemsSource = ds.Tables[0].DefaultView;
oleDbConnection.Close();
Pay attention to changing the connection string to your needs.
You can trim the code, using LINQ:
string colName = (from DataRow dr in dtColumns.Rows where dr[3].ToString().Substring(0, 3) == "QTA" select dr[3].ToString()).ElementAt(0);
I know there are questions like this already, but I've combined all the common code to the answers and still am getting no success, so here I am.
Here's the deal. I have a block of code using SqlDataAdapter.Update to insert new rows into an existing table...
string command = "SELECT * FROM " + tableName;
// Initialize connection
if (oConn == null)
{
oConn = new SqlConnection(mainConnStr);
}
sCmd = new SqlCommand(command, oConn);
sCmd.CommandText = command;
SqlDataAdapter sDA = new SqlDataAdapter(sCmd);
DataSet ds = new DataSet();
oConn.Open();
sDA.Fill(ds, tableName);
oConn.Close();
DataTable dt = ds.Tables[tableName];
//Add each row.
for (int i = 0; i < queryResult.Rows.Count; i++)
{
dt.ImportRow(queryResult.Rows[i]);
}
// Handle the command building for the table update.
SqlCommandBuilder sCB = new SqlCommandBuilder(sDA);
oConn.Open();
sDA.Update(ds, tableName);
oConn.Close();
As mentioned, this works fine. However, if I try very similar code with a two-column test table (testInt, an int non-null; and testSTring, a varchar(50), null-allowed)...
private static void Main(string[] args)
{
SqlConnection = /* Build connection */
string sqlQuery = "SELECT * FROM TestTable WHERE 0 = 1";
SqlDataAdapter sDA = new SqlDataAdapter(sqlQuery, conn);
DataSet dataSet = new DataSet();
conn.Open();
sDA.Fill(dataSet);
conn.Close();
DataRow newRow = dataSet.Tables[0].NewRow();
newRow["testInt"] = 12;
SqlCommandBuilder cb = new SqlCommandBuilder(sDA);
conn.Open();
sDA.Update(dataSet);
conn.Close();
}
This code does nothing, and I can't figure out what in the world the difference is. (I should note that I've also tried using ImportRow instead of the NewRow technique.) Even when I try this block of code with the same tables as the first block (the working block), it still won't update the data.
Therefore, my question is: What fine details must be accounted for when using SqlDataAdapter.Update?
Thanks.
-F
You have to add the row to the DataSet
DataRow newRow = dataSet.Tables[0].NewRow(); // this doesn't add a new row to the data set
dataSet.Tables[0].Rows.Add(newRow); // you have to call this after