I'm using closedxml to read from excelsheets and isert the data to datatable and I'm searching into the datatable at rows where my columnname = "data" and I need to delete all rows from the datatable and I add the new data that came from the search to the datatable again
that's my code
using (var wb = new XLWorkbook(QC_DataEntry, XLEventTracking.Disabled))
{
var ws = wb.Worksheet(1);
DataTable dataTable = new DataTable();
dataTable = ws.RangeUsed().AsTable().AsNativeDataTable();
DataRow[] result = dataTable.Select("Application= '" + Application_Name + "' ");
dataTable.Rows.Clear();
foreach (DataRow row in result)
{
dataTable.Rows.Add(row[0], row[1], row[2]).BeginEdit();
}
}
But I get Error
System.Data.RowNotInTableException: 'This row has been removed from a table and does not have any data. BeginEdit() will allow creation of new data in this row
so how to solve this one or if there another method to search at excelsheet with column name and get only the data i need it will be cool
Thanks
Related
I have a gridcontrol which needs to be populated with some data.
I have created a datatable and populated data in datarow and added to the table. Data is present in table on analysis. Datatable is then set as datasource for grid.
Code is below.
DataTable table = new DataTable();
table.Columns.Add("Tran Date");
table.Columns.Add("Due Date");
table.Columns.Add("Voucher");
table.Columns.Add("Vr No");
table.Columns.Add("Bill Amount");
table.Columns.Add("OutStanding");
table.Columns.Add("Remittance");
table.Columns.Add("Balance");
for (intcount=0;intcount<=BackupFunctions.mdtAgeingTemp.Rows.Count - 1;intcount++)
{
DataRow row = table.NewRow();
row["Tran Date"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][1];
row["Due Date"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][2];
row["Voucher"]= BackupFunctions.mdtAgeingTemp.Rows[intcount][3];
row["Vr No"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][4];
row["Bill Amount"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][10];
row["OutStanding"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][5];
row["Remittance"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][6];
row["Balance"] = BackupFunctions.mdtAgeingTemp.Rows[intcount][7];
table.Rows.Add(row);
}
grdAgeing.DataSource = table;
Its found that 5 rows which is the result is displaying but they are empty. Could you figure out the issue in my code.
From this code I am trying to only display data rows that contain the fields "DBY" in the Station_From_Code column and "MAT" in the Station_To_Column. This will then be printed onto a HTML page. These fields are definitely in the datatable but when I run this cod the table is empty. I am not used to working with data tables in C# so apologies for the poor coding.
dynamic schedluedContent = JsonConvert.DeserializeObject(scheduledJson);
JArray items2 = new JArray();
foreach (JObject stops in schedluedContent.stops)
{
DataTable dt = new DataTable();
DataRow dr;
dr = dt.NewRow();
dr["From_Station_Code"] = stops["station_code"];
dr["To_Station_Code"] = stops["station_code"];
dt.Rows.Add(dr);
DataRow[] result = dt.Select("From_Station_Code = 'DBY' AND To_Station_Code = 'MAT'");
dt.Rows.Add(result);
GridViewTrainTimes.DataSource = dt;
GridViewTrainTimes.DataBind();
}
It's a long time I have not seen this style of code for working with database tables! EntityFramework comes to change and surely ease the way of working with database and prevent different risks of using SQL commands inside the code.
If you use EF, your code will become something like bellow:
var rows = myDBContext.MyTable.Where(x=>x.From_Station_Code == "DBY" && x.To_Station_Code == "MAT");
GridViewTrainTimes.DataSource = rows;
You can use find match rows and add in new datatable, that contains only your match rows data then you can bind this dt to gridview.
DataTable dt = new Datatable(); // Lets this datatable have data;
Datatable dt2 = new Datatable(); // Copy all matching rows
foreach (DataRow dr in dt.Rows)
{
if (dr["From_Station_Code"].ToString() == "DBY" && dr["To_Station_Code"].ToString() == "MAT")
{
dt2.Rows.Add(dr);
}
}
GridViewTrainTimes.DataSource = dt;
GridViewTrainTimes.DataBind();
I don't have problem if i read xml to DataSet:
DataSet temp = new DataSet();
temp.ReadXml(UncompressedStream, System.Data.XmlReadMode.Auto);
But if i use DataTable:
DataTable temp = new DataTable();
temp.ReadXml(UncompressedStream);
then datatable not load data (count of columns and rows equal 0 )
How i can read xml to DataTable
My temporary solution:
DataSet temp = new DataSet();
DataTable structure = new DataTable();
temp.ReadXml(UncompressedStream, System.Data.XmlReadMode.Auto);
structure = temp.Tables[0];
private static void DemonstrateReadWriteXMLDocumentWithString()
{
DataTable table = CreateTestTable("XmlDemo");
PrintValues(table, "Original table");
string fileName = "C:\\TestData.xml";
table.WriteXml(fileName, XmlWriteMode.WriteSchema);
DataTable newTable = new DataTable();
newTable.ReadXml(fileName);
// Print out values in the table.
PrintValues(newTable, "New table");
}
private static DataTable CreateTestTable(string tableName)
{
// Create a test DataTable with two columns and a few rows.
DataTable table = new DataTable(tableName);
DataColumn column = new DataColumn("id", typeof(System.Int32));
column.AutoIncrement = true;
table.Columns.Add(column);
column = new DataColumn("item", typeof(System.String));
table.Columns.Add(column);
// Add ten rows.
DataRow row;
for (int i = 0; i <= 9; i++)
{
row = table.NewRow();
row["item"] = "item " + i;
table.Rows.Add(row);
}
table.AcceptChanges();
return table;
}
This is from: microsoft - xml - datatable
Check that in this code, they add a name for the table, and create the rows and the columns.
LINQ to XML may be a thing you are rather looking for.
Merged with Add new Row to DataTable.
I am trying to add two new Rows to a DataTable. My DataSource consist of a Database with one Table (FooTable) and one column (FooName).
See following code. Only the first Row "Mary" is added and displayed on my DataGrid, but not the second row "Jesus". No exception occurs. Why doesn't it work and what is the correct way to add multiple rows dynamically to DataTable?
/* dg1 = DataGrid; ds = DataSet */
dg1.ItemsSource = ds.Tables;
/* dt = DataTable */
DataRow newRow = dt.NewRow();
newRow["FooName"] = "Mary";
dt.Rows.Add(newRow);
/* add another row to data table */
DataRow newRow2 = dt.NewRow();
newRow2["FooName"] = "Jesus";
dt.Rows.Add(newRow2);
Situation:
Hello! I am trying to populate a WPF toolkit DataGrid with a MS Access database.
Here is what I have right now (it works):
//Load the datagrid with the database
private void LoadDataGrid(string filename, string path)
{
string databaseConn = "Provider=Microsoft.ACE.OLEDB.12.0;" +
"Data Source=" + path + "\\" + filename,
tableName ="";
OleDbConnection conn = null;
DataTable schemaTable,
table = new DataTable();
try
{
conn = new OleDbConnection(databaseConn);
try
{
conn.Open();
schemaTable = conn.GetOleDbSchemaTable(OleDbSchemaGuid.Tables,
new object[] { null, null, null, "TABLE" });
tableName = "[" + schemaTable.Rows[0].ItemArray[2].ToString() + "];";
string sqlQuery = "SELECT * FROM " + tableName;
OleDbCommand command = new OleDbCommand(sqlQuery, conn);
OleDbDataReader reader;
reader = command.ExecuteReader();
table.Load(reader);
DataGrid_.ItemsSource = table.DefaultView;
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
finally
{
conn.Close();
}
}
catch (Exception ex)
{
System.Windows.MessageBox.Show(ex.Message);
}
}
The code sample above loads a WPF toolkit DataGrid with the help of a MS Access database.
What I would like to do is be able to insert a column in the DataGrid at the very beginning. This column would be used to write the row number. What I think could work is to modify the table variable (which is a DataTable object).
Question:
So, how can I insert a column in the table variable, add the row number for each rows in that new column, and have all the data from the database in the DataGrid?
An alternative is to create a column on the DataTable before loading the IDataReader into it.
// the rest of your code
//
DataTable table = new DataTable();
DataColumn col = table.Columns.Add("RowNumber", typeof(int));
col.AutoIncrementSeed = 1;
col.AutoIncrement = true;
//
// the rest of your code
//
table.Load(reader)
//
// the rest of your code
The code snippet bellow demonstrates the technique out of the question's context
//Simulates data coming from a database or another data source
DataTable origin = new DataTable();
DataColumnCollection columns = origin.Columns;
columns.Add("Id", typeof(int));
columns.Add("Name", typeof(string));
origin.Rows.Add(55, "Foo");
origin.Rows.Add(14, "Bar");
IDataReader reader = origin.CreateDataReader();
DataTable table = new DataTable();
//Sets up your target table to include a new column for displaying row numbers
//These are the three lines that make it all happen.
DataColumn col = table.Columns.Add("RowNumber", typeof(int));
col.AutoIncrementSeed = 1;
col.AutoIncrement = true;
//Simulates loading data from the database
table.Load(reader);
// Examine table through the debugger. Is will have the contents of "origin" with the column "RowNumber" prepended
Your easiest solution would be to modify your code to include a "virtual" RowNumber field in your original SELECT query, like so:
SELECT ROWNUM AS ROWNUMBER, * FROM TABLE1
Unfortunately, Access doesn't have anything like a ROWNUM function, so I think the easiest solution is to add a RowNumber column in the SELECT query like this:
SELECT 0 AS ROWNUMBER, * FROM TABLE1
which will add a column containing all zeroes at the beginning, and then iterate through the resulting DataTable and set the row number, like this:
int rownumber = 1;
foreach (DataRow row in table.Rows)
{
row["ROWNUMBER"] = rownumber;
rownumber++;
}
and then dump the DataTable into the grid.