Looping through a DataTable - c#

Well. I have a DataTable with multiple columns and multiple rows.
I want to loop through the DataTable dynamically basically the output should look as follows excluding the braces :
Name (DataColumn)
Tom (DataRow)
Peter (DataRow)
Surname (DataColumn)
Smith (DataRow)
Brown (DataRow)
foreach (DataColumn col in rightsTable.Columns)
{
foreach (DataRow row in rightsTable.Rows)
{
//output
}
}
I typed that out and noticed this would not work. Can someone please advice on a better way of doing this?

foreach (DataColumn col in rightsTable.Columns)
{
foreach (DataRow row in rightsTable.Rows)
{
Console.WriteLine(row[col.ColumnName].ToString());
}
}

foreach (DataRow row in dt.Rows)
{
foreach (DataColumn col in dt.Columns)
Console.WriteLine(row[col]);
}

Please try the following code below:
//Here I am using a reader object to fetch data from database, along with sqlcommand onject (cmd).
//Once the data is loaded to the Datatable object (datatable) you can loop through it using the datatable.rows.count prop.
using (reader = cmd.ExecuteReader())
{
// Load the Data table object
dataTable.Load(reader);
if (dataTable.Rows.Count > 0)
{
DataColumn col = dataTable.Columns["YourColumnName"];
foreach (DataRow row in dataTable.Rows)
{
strJsonData = row[col].ToString();
}
}
}

If you want to change the contents of each and every cell in a datatable then we need to Create another Datatable and bind it as follows using "Import Row". If we don't create another table it will throw an Exception saying "Collection was Modified".
Consider the following code.
//New Datatable created which will have updated cells
DataTable dtUpdated = new DataTable();
//This gives similar schema to the new datatable
dtUpdated = dtReports.Clone();
foreach (DataRow row in dtReports.Rows)
{
for (int i = 0; i < dtReports.Columns.Count; i++)
{
string oldVal = row[i].ToString();
string newVal = "{"+oldVal;
row[i] = newVal;
}
dtUpdated.ImportRow(row);
}
This will have all the cells preceding with Paranthesis({)

Related

Checking value in column foreach row

The DataTable (dt) stores the retrieved values of carID's and makes so it stores like 3 rows within the DataTable, I also have another DataTable called dt2 which also stores carID's and makes, I am trying to loop through each row in the dt to see if any carID stored in the dt exists in any of the rows in dt2, here is what I have so far:
DataTable dt = w.getUserCars(userID);
foreach (DataRow dr in dt.Rows)
{
string carID = dr["carID"].ToString();
}
How do I do this?
You should be able to achieve this using DataTable.Select() method. You are on the right track. You just need to add the method to find the Row(s) in dt2.
DataTable dt = w.getUserCars(userID);
DataRow[] foundRows;
foreach (DataRow dr in dt.Rows)
{
string carID = dr["carID"].ToString();
foundRows = dt2.Select("carID = " + carID);
// do stuff here with foundRows
foreach (DataRow r in foundRows)
{
r.Delete();
}
}

How to store data grid into datatable?

I need to store datagridview selected rows into datatable in single columns like below
DataGridView
user1 user2 user3
ram sam ravi
DataTable
values
ram
sam
ravi
I tried below code
DataTable dt = new DataTable();
dt.Columns.Add("values",typeof(string));
foreach (DataGridViewRow gridRow in dataGridView_settings.Rows)
{
DataRow dtRow = dt.NewRow();
for (int i = 0; i < dataGridView_settings.Columns.Count; i++)
{
dtRow[0] = gridRow.Cells[i].Value;
dt.Rows.Add(dtRow);
}
}
Problem is its adding only one row in the datatable then showing error "This row already belongs to this table."
You should move the DataRow creation to the inner for
DataTable dt = new DataTable();
dt.Columns.Add("values",typeof(string));
foreach (DataGridViewRow gridRow in dataGridView_settings.Rows)
{
for (int i = 0; i < dataGridView_settings.Columns.Count; i++)
{
DataRow dtRow = dt.NewRow();
dtRow[0] = gridRow.Cells[i].Value;
dt.Rows.Add(dtRow);
}
}

Delete Row From Data Table

I want to Delete the Multiple records from the DataTable
For example :
in my case PaperId is Repeating several Times.I want to Delete it all Duplicate records.
i have written code but loop is giving error
DataSet ds = new DataSet();
sqlDad.Fill(ds);
DataTable dt1 = new DataTable();
ds.Tables.Add(dt1);
dt1 = ds.Tables[0];
DataTable dt2 = new DataTable();
dt2 = dt1;
List<DataRow> rowsToDelete = new List<DataRow>();
foreach(DataRow dr in ds.Tables[0].Rows)
{
int r = ds.Tables[0].Columns.Count;
string x = dr.ItemArray[0].ToString();
int counter = 0;
foreach (DataRow dr1 in ds.Tables[0].Rows)
{
if (x == dr1.ItemArray[0].ToString())
{
counter++;
}
if (counter > 1)
{
rowsToDelete.Add(dr1);
foreach (DataRow row in rowsToDelete)
{
dt2.Rows.Remove(row);
}
dt2.AcceptChanges();
rowsToDelete.Clear();
}
}
Using the DefaultView of the DataTable and setting the sort order on the column that you don't want repeats to appear. You could loop over the rows and delete all the rows after the first one
// Work on the first table of the DataSet
DataTable dt1 = ds.Tables[0];
// No need to work if we have only 0 or 1 rows
if(dt1.Rows.Count <= 1)
return;
// Setting the sort order on the desidered column
dt1.DefaultView.Sort = dt1.Columns[0].ColumnName;
// Set an initial value ( I choose an empty string but you could set to something not possible here
string x = string.Empty;
// Loop over the row in sorted order
foreach(DataRowView dr in dt1.DefaultView)
{
// If we have a new value, keep it else delete the row
if(x != dr[0].ToString())
x = dr[0].ToString();
else
dr.Row.Delete();
}
// Finale step, remove the deleted rows
dt1.AcceptChanges();
Try This
DataRow[] rows;
rows=dataTable.Select("UserName = 'ABC'"); // UserName is Column Name
foreach(DataRow r in rows)
r.Delete();
If you want to remove the entire row from DataTable ,
try this
DataTable dt = new DataTable(); //User DataTable
DataRow[] rows;
rows = dt.Select("UserName = 'KarthiK'");
foreach (DataRow row in rows)
dt.Rows.Remove(row);

Listview to datatable

I have a listview and I NEED to load the rows and columns into datatable.
I have tried as follows
DataTable dt = new DataTable();
foreach (ListViewItem item in listView1.Items)
{
table.Columns.Add(item.ToString());
foreach (var it in item.SubItems)
dt.Rows.Add(it.ToString());
}
When I retrieved the rowcount and columncount then I got number of rows as column count and number of column as rowcount
dont know what's going on..
please help me
best regards
Bunzitop
its a long time ago, but someone will probably struggle about this in the future,
so here is my solution to convert a ListView to a DataTable:
DataTable dtZeitplan = new DataTable();
foreach (ColumnHeader chZeitplan in lvZeitplan.Columns)
{
dtZeitplan.Columns.Add(chZeitplan.Text);
}
foreach (ListViewItem item in lvZeitplan.Items)
{
DataRow row = dtZeitplan.NewRow();
for(int i = 0; i < item.SubItems.Count; i++)
{
row[i] = item.SubItems[i].Text;
}
dtZeitplan.Rows.Add(row);
}
You are doing it so wrong. You need 1 + listView1.Items[0].SubItems.Count columns in your DataTable (the 1 is for ListViewItem and others are subitems) and listView1.Items.Count number of rows. Therefore your code should be like this:
if (listView1.Items.Count > 0)
{
dt.Columns.Add();
foreach (ListViewItem.ListViewSubItem lvsi in listView1.Items[0].SubItems)
dt.Columns.Add();
//now we have all the columns that we need, let's add rows
foreach (ListViewItem item in listView1.Items)
{
List<string> row = new List<string>();
row.Add(item.ToString());
foreach (var it in item.SubItems)
row.Add(it.ToString());
//Add the row into the DataTable
dt.Rows.Add(row.ToArray());
}
}
DataTable table = new DataTable();
table.Columns.Add("MODUL", typeof(string));
table.Columns.Add("ACIKLAMA", typeof(string));
table.Columns.Add("UZUNLUK", typeof(string));
table.Columns.Add("GENISLIK", typeof(string));
table.Columns.Add("MIKTAR", typeof(string));
for (int i = 0; i < listView2.Items.Count; i++)
{
table.Rows.Add(listView2.Items[i].SubItems[1].Text, listView2.Items[i].SubItems[2].Text, listView2.Items[i].SubItems[3].Text, listView2.Items[i].SubItems[4].Text, listView2.Items[i].SubItems[5].Text);
}
You can use the ItemsSource property and System.Data classes (ADO.Net) to bind a listview to a datatable and vise-verse (what you want). The following code will give you a datatable from an existing bound ListView control.
DataView theDataView = (DataView)theListView.ItemsSource;
DataTable theDataTable = theDataView.Table;
Manish Mishra asked what your listview control is bound to. This is a very good question. My answer assumes it is already bound to a datatable.
Working code from VB.Net: Just replace your listview name with "LVActions"
Dim it As Integer = 0
Dim dt As New DataTable
For it = 0 To LVActions.Items(0).SubItems.Count - 1
Dim DCOL As New DataColumn(LVActions.Columns(it).Text)
dt.Columns.Add(DCOL)
Next
For it = 0 To LVActions.Items.Count - 1
Dim DROW As DataRow = dt.NewRow
For j As Integer = 0 To LVActions.Items(it).SubItems.Count - 1
DROW(LVActions.Columns(j).Text) = LVActions.Items(it).SubItems(j).Text
Next
dt.Rows.Add(DROW)
Next

Make a copy of a Datatable with some changes

I am trying to make a copy of a DataTable dt1 to a new one dt2.
dt1 contains columns of string and boolean types.
dt2 will contains only string types.
The following is my code which works fine.
public DataTable Convert(DataTable dt1)
{
try
{
var dt2 = dt1.Clone();
foreach (DataColumn dc in dt2.Columns)
{
dc.DataType = Type.GetType("System.String");
}
foreach (DataRow row in dt1.Rows)
{
dt2.ImportRow(row);
}
foreach (DataRow dr in dt2.Rows)
{
foreach (DataColumn dc in dt2.Columns)
{
bool value;
if (bool.TryParse(dr[dc].ToString(), out value))
{
dr[dc] = "+";
}
}
}
return dt2;
}
finally
{
}
}
1st step: Clone of dt1 and change the columns types to string.
2nd step: Import the rows from dt1 to dt2
3rd step: Change all true values to "+"
Is there a better way to perform those steps. "better" mean clearer, simpler, less code, less steps, better performance.
The code you've provided very clearly describes your intent and is succinct. We can however make some optimizations that will help with performance.
You are attempting to parse every field of every row instead of determining which fields actually require manipulation. As the number of non-boolean columns increases you're doing more work than is needed.
You already have the original table which contains bool values so you could do away with parsing all together.
Here is a version that optimizes around these two points. The code is not shorter or more elegant, but it will require no text parsing and far fewer evaluations.
public DataTable Convert2(DataTable dt1)
{
DataTable dt2 = dt1.Clone();
// Alter all columns datatype
foreach (DataColumn col in dt2.Columns)
col.DataType = typeof(string);
// Import all rows from existing table
foreach (DataRow row in dt1.Rows)
dt2.ImportRow(row);
// Index the boolean columns that will require evaluation
List<int> booleans = new List<int>();
foreach (DataColumn col in dt1.Columns)
{
if (col.DataType == typeof(bool))
booleans.Add(col.Ordinal);
}
// Since two tables will be identical except for datatypes
// iterate over original table and cast instead of performing
// a string conversion and parsing the result.
for (int row = 0; row < dt1.Rows.Count; row++)
{
foreach (int index in booleans)
{
if ((bool) dt1.Rows[row][index])
dt2.Rows[row][index] = "+";
}
}
return dt2;
}
Additionally, I left out the try..finally block since you're not using it.
That code would do the job.
public DataTable Convert(DataTable dt1)
{
try
{
var dt2 = dt1.Clone();
foreach (DataColumn dc in dt2.Columns)
{
dc.DataType = Type.GetType("System.String");
}
foreach (DataRow row in dt1.Rows)
{
dt2.ImportRow(row);
DataRow dr = dt2.Rows[dt2.Rows.Count-1]
foreach (DataColumn dc in dt2.Columns)
{
bool value;
if (bool.TryParse(dr[dc].ToString(), out value))
{
dr[dc] = "+";
}
}
}
return dt2;
}
finally
{
}
}

Categories

Resources