Remove TableCell from each TableRow c# - c#

I have used C# Table to display HTML Table in aspx page. I want to remove column from that Table.
DataTable getTxnOutput = // Get DataTable by Calling Stored Procedure;
Table txnOutputs = Generix.convertDataTable2HTMLTable(getTxnOutput);
foreach (TableRow trOutput in txnOutputs.Rows)
{
if (trOutput.TableSection == TableRowSection.TableBody)
{
/* Here i am doing some operation using column which i want to delete afterwards */
txnOutputs.Rows[0].Cells.Remove(trOutput.Cells[6]); //Now delete that column
}
}
Page.Controls.Add(txnOutputs);
But above code will delete cell only in first row.
How can I delete in every row without using further more loops.
I found Solution but can i incorporate same in above loop... I just want to avoid two loops..
for (int k = 0; k < txnOutputs.Rows.Count; k++)
{
txnOutputs.Rows[k].Cells.Remove(txnOutputs.Rows[k].Cells[6]);
}

Shouldn't this line
txnOutputs.Rows[0].Cells.Remove(trOutput.Cells[6]);
be
trOutput.Cells.Remove(trOutput.Cells[6]);?

Try this:
DataTable getTxnOutput = // Get DataTable by Calling Stored Procedure;
Table txnOutputs = Generix.convertDataTable2HTMLTable(getTxnOutput);
int i = 0;
foreach (TableRow trOutput in txnOutputs.Rows)
{
if (trOutput.TableSection == TableRowSection.TableBody)
{
/* Here i am doing some operation using column which i want to delete afterwards */
txnOutputs.Rows[i].Cells.Remove(trOutput.Cells[6]); //Now delete that column
}
i++;
}
Page.Controls.Add(txnOutputs);

You will have to include the forloop inside if, and use a Variable something like viewstate[X]=1 inside if statement, and check
if(viewstate[X]==1)
{
// logic here
}
viewstate[X]=0;
run for loop
after end of For loop set viewstate[X]=0
so that you can run for loop only once else it will loop through every row.

Related

Update :Result is not transfered to the orginal dataset. Sorting Rows in Dataset using C#

Update: even though I have got the required result but when the the second function access the data table the value is still the same
It a sequential program with two functions in different classes. First sort and second replace function. So it should sort the value and other function should be able to retrieve the sorted table but when it retrieve the datatable it gives the unsorted table.
I have used acceptchanges() but it also give the same result.
The program is trying to sort the table according to the required field and the result is stored in Sorted table variable. I am trying to copy this to the original i-e sourceTables but it is not working and is adding another row instead of updating [As shown in below dig]. I have tried to copy whole table but it does not work and by adding rows it is not giving the required result. I have used different methods but I am not getting the required result.
List<DataTable> sourceTables = context.GetDataByTable(sourceTable.StringValue);
List<DataTable> targetTables = context.GetDataByTable(targetTable.StringValue, sourceTables.Count);
string orderDesc= orderField.StringValue + " DESC";
for (int i = 0; i < sourceTables.Count; i++)
{
DataView dv = sourceTables[i].DefaultView;
if (orderDirection.StringValue == OrderDirectionAsc)
{
// for Sorting in Ascending Order
dv.Sort = orderField.StringValue;
}
else
{
// for Sorting in Descending Order
dv.Sort = orderDesc;
}
DataTable sortedTable = dv.ToTable();
DataTable dttableNew = sortedTable.Clone();
//sourceTables[i] = sortedTable.Copy();
//targetTables[i] = dv.ToTable();
//targetTables[i] = sortedTable.Copy();
// foreach (DataRow dr in sortedTable.Rows)
//// targetTables[i].Rows.Add(dr.ItemArray);
//}
for (int j = 0; j < sourceTables[i].Rows.Count; j++)
{
if (sourceTable.GetValue().ToString() == targetTable.GetValue().ToString())
{
foreach (DataRow dr in sortedTable.Rows)
{
targetTables[i].Rows.Add(dr.ItemArray);
}
else
{
foreach (DataRow dr in sortedTable.Rows)
{
targetTables[i].Rows.Add(dr.ItemArray);
}
// targetTables[i] = sortedTable.Copy(); does not work
//foreach (DataRow drtableOld in sortedTable.Rows)
//{
// targetTables[i].ImportRow(drtableOld);
//}
Instead of replacing the first values it is adding more rows
any help would be appreciated
If any one have problem with duplicate data or the changes are only local and is not effecting the original data table. Remember to always use .ImportRow(dr) function to add rows to the table and if you use Tables[i].Rows.Add(dr.ItemArray); the changes will affect only the local table and not the original one. Use .clear to remove the old rows from the orginal table. The action done directly on the original function will only effect the rows. If it is done on the clone copy changes will nor affect the original table.
Here is the complete code
DataTable sortTable = dv.ToTable();
if (sTable.GetValue().ToString() == tTable.GetValue().ToString())
{
sTables[i].Clear();
foreach (DataRow dr in sortTable.Rows)
{
sTables[i].ImportRow(dr);
}
sTables[i].AcceptChanges();
}

Delete row in DGV if int is incremented?

I have a method to save each row in a datagridview into the database, but I want to remove each row if it gets saved. I have this method:
public static void SaveMajEq(MajorEquipment_CreateView CView)
{
rowCount = 0;
// For each cell in the DataGrid, stores the information in a string.
for (rows = 0; rows < CView.dgvCreate.Rows.Count; rows++)
{
if (CView.dgvCreate.Rows[rows].Cells[col].Value != null)
{
// Creates a model, then populates each field from the cells in the table.
MeModel = new MajorEquipment_Model();
MeModel.EquipmentNumber = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[0].Value);
MeModel.EquipmentType = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[1].Value);
MeModel.Location = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[2].Value);
MeModel.Notes = Convert.ToString(CView.dgvCreate.Rows[rows].Cells[3].Value);
Database_Facade.Operation_Switch(OPWRITE);
}
CView.dgvCreate.Rows.RemoveAt(rows);
}
MessageBox.Show(rowCount + " Entries stored in database.");
}
rowCount gets incremented in a try/catch method in a separate class, so if anything occurs, it wont be incremented. What I want to do is only implement this line:
CView.dgvCreate.Rows.RemoveAt(rows);
only if rowCount is incremented each time. I'm not sure how to implement this.
Revert the loop order
for (rows = CView.dgvCreate.Rows.Count - 1; rows >= 0 ; rows--)
Looping backward allow to remove the row processed by the loop without affecting the index of the next row to process.

Using datagrid values in a switch statement

In my program I have a datagridview table c_tbl which gets data from a SQL Server and populates the datagridview. I have a for loop running through each row. Now I have a switch statement that should check each row and get the value so I can compare it and add other data in that row.
This is what it looks like
for(int i=0; i<c_tbl.rows.count; i++){
switch("this is where i need the argument that will check the row and column value)
{
case "string value that gets compared"
//add in values to column on same row.
}
}
I originally had something like
switch(c_tbl.Column[0][i])
but it's not working.
You can loop through the DataTable like this:
foreach (DataRow row in c_tbl.Rows)
{
foreach (DataColumn col in c_tbl.Columns)
{
switch (row[col].ToString())
{
}
}
}

Delete row from datatable where first column does not contain (some string)

I have DataTable with the following columns:
ClientID date numberOfTransactions price
ClientID is of type string and I need to ensure that its contents include "A-" and "N6" for every value in the table.
I need to delete all rows from the DataTable where this first column (ClientID) does not contain both "A-" and "N6" (some totals and other unnecessary data). How can I select and delete these rows specifically from the DataTable?
I know this:
foreach (DataRow row in table.Rows) // Loop over the rows.
{
//Here should come part "if first column contains mentioned values
}
I also know this
If (string.Contains("A-") == true && string.Contains("N6") == true)
{
//Do something
}
I need help how to implement this for first column of each row.
Try this:
EDIT: Totally messed up that last line, so if you tried it, try it now that I made it not stupid. =)
List<int> IndicesToRemove = new List<int>();
DataTable table = new DataTable(); //Obviously, your table will already exist at this point
foreach (DataRow row in table.Rows)
{
if (!(row["ClientID"].ToString().Contains("A-") && row["ClientID"].ToString().Contains("N6")))
IndicesToRemove.Add(table.Rows.IndexOf(row));
}
IndicesToRemove.Sort();
for (int i = IndicesToRemove.Count - 1; i >= 0; i--) table.Rows.RemoveAt(IndicesToRemove[i]);
try using this,
assuming dt as your Datatabe object and ClientID as your first column (hence using ItemArray[0])
for(int i=0; i<dt.Rows.Count; i++)
{
temp = dt.Rows[i].ItemArray[0].ToString();
if (System.Text.RegularExpressions.Regex.IsMatch(temp, "A-", System.Text.RegularExpressions.RegexOptions.IgnoreCase) || System.Text.RegularExpressions.Regex.IsMatch(temp, "N6", System.Text.RegularExpressions.RegexOptions.IgnoreCase))
{
dt.Rows.RemoveAt(i);
i--;
}
}
Simple and straight forward solution... hope it helps
this should be more efficient, both in lines of Code and Time, try this :)
for(int x=0; x<table.Rows.Count;)
{
if (!table.Rows[x].ItemArray[0].contains("A-") && !table.Rows[x].ItemArray[0].contains("N6"))
table.Rows.RemoveAt(x);
else x++;
}
Happy Coding
Preface: C.Barlow's existing answer is awesome, this is just another route someone could take.
This is one way to do it where you never have to loop all the way through the original table (by taking advantage of the DataTable.Select() method):
DataTable table = new DataTable(); // This would be your existing DataTable
// Grab only the rows that meet your criteria using the .Select() method
DataRow[] newRows = table.Select("ClientID LIKE '%A-%' AND ClientID LIKE '%N6%'");
// Create a new table with the same schema as your existing one.
DataTable newTable = table.Clone();
foreach (DataRow r in newRows)
{
// Dump the selected rows into the table.
newTable.LoadDataRow(r.ItemArray, true);
}
And now you have a DataTable with only the rows you want. If necessary, at this point you could clear out the original table and replace it with the contents of the new one:
table.Clear();
table = newTable.Copy();
Edit: I thought of a memory optimization last night, you can just overwrite the existing table once you have the rows you need, which avoids the need for the temporary table.
DataTable table = new DataTable(); // This would be your existing DataTable
// Grab only the rows that meet your criteria using the .Select() method
DataRow[] newRows = table.Select("ClientID LIKE '%A-%' AND ClientID LIKE '%N6%'");
// Clear out the old table
table.Clear();
foreach (DataRow r in newRows)
{
// Dump the selected rows into the table.
table.LoadDataRow(r.ItemArray, true);
}

Where does DataRowCollection.Add method insert the new row?

I'm trying to figure out where DataRowCollection.Add(DataRow row) inserts the new row into its datatable. Is it at the end of the table, like an append? Is it random?
Also, I want to use this while I'm for looping through a datatable. If some condition exists, add a new row containing different data to run through the For loop to the end of the datatable. Are there any specific problems with this approach? How else might I handle it?
EDIT: I am For Looping through a .Net DataTABLE stored in memory. I'm not touching the dataBASE where the original data is stored during this looping operation. The DataTABLE is populated prior to the loop and is not a problem.
Here is relavant code:
DataTable machineANDlastDate = new DataTable();
//Populate machineANDlastDate
for (int i = 0; i < machineANDlastDate.Rows.Count; i++)
{
lastFutureDate = DateTime.Parse(machineANDlastDate.Rows[i]["MaxDueDate"].ToString());
newDateTime = lastFutureDate.AddDays(frequency); //This is where the new date is created.
machineSerial = machineANDlastDate.Rows[i]["machineSerial"].ToString();
if (newDateTime < DateTime.Now)
{
machineANDlastDate.Rows.Add(new String[] { machineSerial, newDateTime.AddDays(frequency).ToString() });
continue;
}
...Removed for irrelevancy...
}
Is this a valid way to add a row to the end of the datatable?
As far as I know, it is always added to the end of the collection.
If you for loop through the database, there shouldn't be a problem, if you begin at the beginning of the data table and finish at the end of it or smth similar. However, you will then also loop through the newly created data rows, and I don't know whether you want to achieve this. You only could get problems if you take a foreach loop instead because it cannot handle modifications of the underlying collection.
If you want to know if a row is new or not you can check the DataRow.RowState property.
// your code to add rows
...
// process added rows
foreach (DataRow row in machineANDlastDate.Rows)
{
if (row.RowState == DataRowState.Added)
{
// do stuff
}
}
// now confirm new rows (they won't have a RowState of Added after this)
machineANDlastDate.AcceptChanges();
It's always at the end of the table, as far as i know most of the DataBase conectors, whe you use their add row, its always at the end.
The Add method will insert a DataRow into a DataRowCollection object only. To actually add the DataRow to the data table, you will need to call the NewRow method which appends itself onto the DataTable, and thus appends the row to the table in that database. For reference, check out http://msdn.microsoft.com/en-us/library/9yfsd47w.aspx

Categories

Resources