C# DataTable delete row - c#

I have DataTable participantAccounts which is not connected to any database or something.
How can I delete a row from it?
This is not working :
for (int i = participantAccounts.Rows.Count - 1; i >= 0; i--) {
DataRow dr= participantAccounts.Rows[i];
if (Equals(dr["sellrMembId"].ToString(), itemId))
participantAccounts.Rows.RemoveAt(i);
}
participantAccounts.AcceptChanges();
It acts like everything is fine but row still remains in DataTable.
I also tried dr.Delete() but that neither works.
When I try participantAccounts.Rows.Remove(dr) I get an exception The given DataRow is not in the current DataRowCollection.
What I am doing wrong?

if (participantAccounts.Rows.Contains(itemId))
{
DataRow foundRow = participantAccounts.Rows.Find(itemId);
participantAccounts.Rows.Remove(foundRow);
}

for (int i = participantAccounts.Rows.Count - 1; i >= 0; i--)
{
DataRow dr= participantAccounts.Rows[i];
if (Equals(dr["sellrMembId"].ToString(), itemId))
{
participantAccounts.Rows.Delete();
participantAccounts.AcceptChanges();
}
}

Finally I found the solution.
IT had nothing to do with way how rows were deleted.
DataTable dt = participantAccounts;
dt.Rows.Remove(dt.Rows.Find(itemId));
participantAccounts = dt;
the problem was, I think, participantAccounts was a viewstate (.ASP) , and it for that reason it was not updated with direct approach.
Thank everyone for help

You should use Delete instead of RemoveAt.
So your code could look like:
for (int i = participantAccounts.Rows.Count - 1; i >= 0; i--)
{
var dr= participantAccounts.Rows[i];
if (object.Equals(dr["sellrMembId"], itemId))
dr.Delete();
}
participantAccounts.AcceptChanges();
Note: your deleted DataRows will present in DataTable and have RowStatus = Deleted until you will call AcceptChanges method on DataTable. After calling AcceptChanges, deleted DataRows will be removed from the table.
See MSDN for reference on DataRow.Delete method.

int index = -1;
for (int i = participantAccounts.Rows.Count - 1; i >= 0; i--)
{
DataRow dr= participantAccounts.Rows[i];
if (Equals(dr["sellrMembId"].ToString(), itemId))
{
index = i;
break;
}
}
participantAccounts.Rows.RemoveAt(index);
participantAccounts.AcceptChanges();

This should do the work..
dataSet1.Customers.Rows[0].Delete();
OR
dataSet1.Tables["Customers"].Rows[0].Delete();
How to: Delete Rows in a DataTable

You should use foreach loop to get each row and find particular row which you want to remove. Below is code snippets.
foreach (DataRow row in participantAccounts.Rows)
{
if (row["sellrMembId"].ToString() == itemId)
{
participantAccounts.Rows.Remove(row);
participantAccounts.AcceptChanges();
break;
}
}

Related

Check empty rows in datatable in Visual Studio 2005, no LINQ

I've uploaded data to a datatable from a excel file. Whats the best way to check empty rows in datatable. NB: Need solution for Visual Studio 2005. Cant use linq.
foreach (DataRow row in result.Rows)
{
//check if row is empty
//if not continue processing data
//else remove the row from datatable
}
Currently the solution in my mind is inside foreach loop, put another foreach loop and check each column. If all columns are null, remove the row from datatable.
Is there any other best method. Does the above method takes more time to execute as there is another for each loop. There will be lots of rows in the datatable.
Edited:
I've got one code:
private bool checkIfRowEmpty(DataRow row)
{
var r = (DataRow)row;
int emptyCount = 0;
int itemArrayCount = r.ItemArray.Length;
foreach (var i in r.ItemArray) if (string.IsNullOrWhiteSpace(i.ToString())) emptyCount++;
if (emptyCount == itemArrayCount) return false;
else return true;
}
Is this okay? Or should I use any solution from below? Which one is good?
Here is one approach - to iterate through all rows and all columns
DataTable table = new DataTable();
List<int> rowsToRemove = new List<int>();
for (int i = 0; i < table.Rows.Count; i++)
{
DataRow row = table.Rows[i];
foreach (DataColumn col in row.Table.Columns)
{
bool skip = false;
if (row[col] != null)
{
//this column is not null, so mark skip flag as true
skip = true;
}
if (skip)
//this row should be skipped because it has at least one column that isn't null
break;
else
rowsToRemove.Add(i);
//mark this row's index for deletion
}
}
//loop through list in reverse order and remove rows by their index
for (int i = rowsToRemove.Count; i > 0; i--)
table.Rows.RemoveAt(i);
Best solution I can think of is the following one:
public bool IsRowEmpty(DataRow row)
{
if (row == null)
return true;
foreach(var value in row.ItemArray)
{
if (value != null)
return false;
}
return true;
}
Then from your main code:
foreach (DataRow row in result.Rows)
{
if(!IsRowEmpty(row))
{
// Row is not empty.
}
}
Hello,
You can simply achive this using DataView : like this -
DataView dv = yourTable.DefaultView;
dv.Sort = "column_1,column_2";
DataTable dtNew = dv.ToTable(true, "column_1", "column_2",...,"column_n"); // please mention all columns here
dtNew.Rows.RemoveAt(0);

Add specific rows from dataGridView depending on search value

Following issue:
I have a datatable and a list which contains specific values.
routIds = col1Items.Distinct().ToList();
String searchValue = String.Empty;
int rowIndex = -1;
for (int i = 0; i < routIds.Count; i++)
{
searchValue = routIds[i];
foreach (DataGridViewRow row in form1.dataGridView5.Rows)
{
if (row.Cells[form1.routingIdBox.Text].Value != null) // Need to check for null if new row is exposed
{
if (row.Cells[form1.routingIdBox.Text].Value.ToString().Equals(searchValue))
{
rowIndex = row.Index;
foreach (DataGridViewColumn column in form1.dataGridView5.Columns)
dtRout.Columns.Add(column.Name);
for (int k = 0; k < form1.dataGridView5.Rows.Count; k++)
{
dtRout.Rows.Add();
for (int j = 0; j < form1.dataGridView5.Columns.Count; j++)
{
datTable.Rows[k][j] = form1.dataGridView5.Rows[rowIndex].Cells[j].Value;
}
}
}
}
}
}
I want to search the first column from my datagridview and check if it matches a specific value (from my array - routIds). If yes then I want to add the whole row into a datatable but I don't know how this works exactly. Tried around but I get exceptions (specific row not found).
Assuming you have a DataTable as your underlying DataSource. I would not iterate through the DataGridViewRows.
DataTable dataSource = dataGridView.DataSource as DataTable; // if it is a DataTable. If not, please specify in your question
// let's make a DataTable, which is a copy of your DataSource
DataTable dataTableFoundIds = new DataTable();
foreach (DataColumn column in dataSource.Columns)
dataTableFoundIds.Columns.Add(column.ColumnName, column.DataType);
// iterate through your routeIds
foreach (int id in routeIds)
{
var row = dataSource.AsEnumerable().FirstOrDefault(item => item["col1"].Equals(id)); // take the first row in your DataSource that matches your routeId
if (row != null)
{
dataTableFoundIds.Rows.Add(row.ItemArray); // if we find something, insert the whole row of our source table
}
}
Hope this helps!
UPDATE: if you want to find all occurances:
foreach (int id in routeIds)
{
var rows = dataSource.AsEnumerable().Where(item => item["col1"].Equals(id)); // take all rows in your DataSource that match your routeId
foreach(var row in rows)
{
dataTableFoundIds.Rows.Add(row.ItemArray); // if we find something, insert the whole row of our source table
}
}

datatable get specific column from row

I have the following:
//a datatable with some rows and columns lets say 5x5
var datatable = new DataTable();
var numberofrows = datatable.rows.count;
for (int i = 0; i < numberofrows; i++) {
//for each row, get the 3rd column
var cell = datatable.rows[i].???
}
how do I get the 3rd column for each row?
for 3rd column
var cellValue = datatable.Rows[i][2];
better, if you know the column name,
var cellValue = datatable.Rows[i]["column_name"];
If the table contains 2 columns "Property" and "Value". Contents can be inserted as follows
table.Columns.Add("Property", typeof(string));
table.Columns.Add("Value", typeof(string));
table.Rows.Add("P1", "abc");
table.Rows.Add("P2", "xyz");
To retrive contents of specific column
foreach (DataRow row in table.Rows)
{
if (row["Property"].ToString() == "P1")
{
var value = row["Value"].ToString();
}
}
we can read the particular column values by like this
foreach (DataTable table in ds.Tables)
{
if (table.TableName == "Table1")
{
for (int j = 0; j < table.Rows.Count; j++)
{
int a = Convert.ToInt32( table.Rows[j].ItemArray[3]);
int b = Convert.ToInt32(table.Rows[j].ItemArray[4]);
}
}
}
You can iterate thru the datatable and get every row, which can be thought as an array, so you can pick each element of that particular row using an index (and can also use the name of the column instead of the index, i.e.: row["column3 name"]).
foreach(DataRow row in datatable)
{
Console.WriteLine(row[2]);
}

Add range rows from one DataTable to another

Have a DataTable and I need to create another one having a subset range of rows from the first. So I want the second DataTable to have row n till n + y from the first one. How can I do this please?
DataTable limitData = new DataTable();
for (int rowIndex = startingRow; rowIndex < endingRow; rowIndex++)
{
limitData.Rows.Add(columnarData.Rows[rowIndex].ItemArray);
}
gives an error: "Input array is longer than the number of columns in this table."
The code is in C# .NET 4.0
try this and let me hear from if this works
DataTable limitData =limitData.Clone();
for (int rowIndex = startingRow; rowIndex < endingRow; rowIndex++)
{
limitData.Rows.Add(columnarData.Rows[rowIndex].ItemArray);
}
or
DataTable limitData =limitData.Clone();
foreach (DataRow dr in columnarData.Rows)
{
limitData.Rows.Add(dr);
}
try this
for (DataRow r in dt.Rows)
{
if(some condition))
{
extractedData.ImportRow(r);
}
}
Union() also work:
dt1 = dt1.AsEnumerable().Union(dt2.AsEnumerable()).CopyToDataTable();
Reference from this post.

Error in datarow,Collection was modified; enumeration operation might not execute [duplicate]

This question already has answers here:
How do I loop through items in a list box and then remove those item?
(8 answers)
Closed 9 years ago.
I have for-each loop in which the data row is updated so the exception ,Collection was modified; enumeration operation might not execute is generated. any way to fix it? i have seen To-List function but it is not working with data row , here is my code:
foreach (DataRow row in dataTable.Rows) {
temp = row[0].ToString();
foreach (DataRow rows in dataTable.Rows) {
if (temp == rows[0].ToString()) {
tempdatatable.Rows.Add(row[0],row[1]);
dataTable.Rows.Remove(rows);
//Update happens here
}
tempdatatable.DefaultView.Sort = "gscitations DESC";
dataGridView1.DataSource = tempdatatable;
}
}
You cannot modify collection while enumerating it using Enumerator, which is happening behind the scene of the foreach statement (MDSN link).
One possible way to solve this problem is to collect rows to be deleted in the first enumeration and than remove them in the separate loop like this:
var rowsToDelete = new List<DataRow>();
foreach (DataRow row in dataTable.Rows)
{
temp = row[0].ToString();
foreach (DataRow rows in dataTable.Rows)
{
if (temp == rows[0].ToString())
{
tempdatatable.Rows.Add(row[0],row[1]);
rowsToDelete.Add(rows);
}
tempdatatable.DefaultView.Sort = "gscitations DESC";
dataGridView1.DataSource = tempdatatable;
}
}
rowsToDelete.ForEach( x => dataTable.Rows.Remove(x) );
You can also replace foreach loop with for, but you need to do extra work properly handling the current index while deleting the elements.
Try this :
for (int i = 0; i < dataTable.Rows.Count; i++)
{
var tempRow = dataTable.Rows[i];
var temp = dataTable.Rows[i][0];
for (int j = 0; j < dataTable.Rows.Count; j++)
{
DataRow rows = dataTable.Rows[j];
if (temp == rows[0].ToString())
{
tempdatatable.Rows.Add(tempRow[0], tempRow[1]);
dataTable.Rows.Remove(rows); //Update happen here
}
tempdatatable.DefaultView.Sort = "gscitations DESC";
dataGridView1.DataSource = tempdatatable;
}
}
I would say that you should make a separate table of entries, and instead of calling datatable.Rows.Remove(rows), add the row "rows" to this other table. Then, whenever row or rows iterates, you run an if statement to check if its been "deleted", i.e., in the list of deleted rows. After the enumeration is over, you can then delete those rows permanently from the table.
EDIT:
Here's the code implementation:
DataTable duplicates = dataTable;
duplicates.Rows.Clear(); /* Produces an empty duplicate of the
dataTable table to put the duplicates in */
foreach (DataRow row in dataTable.Rows)
{
if (!duplicates.Rows.Contains(row))
{
temp = row[0].ToString();
foreach (DataRow rows in dataTable.Rows)
{
if (temp == rows[0].ToString()&&!duplicates.Rows.Contains(rows)) //need unique key
{
tempdatatable.Rows.Add(row[0],row[1]);
}
tempdatatable.DefaultView.Sort = "gscitations DESC";
dataGridView1.DataSource = tempdatatable;
}
}
}
foreach (DataRow row in duplicates.Rows)
{
dataTable.Rows.Remove(row);
}
if you don't have a unique key, you can try switching !duplicates.Rows.Contains(/*specific row*/) for duplicates.Rows.IndexOf(/*specific row*/)>0. That should provide an adequate substitute.

Categories