Converting a List into Datatable - c#

Assume that I have a list like PL = { P1, 0, 10, P2, 5, 20 } and I need to convert it a datatable like
ProcessName ArrivalTime CpuTime
P1 0 10
P2 5 20
The number of process (row count) is dynamic. And I have tried sth like this:
protected DataTable CreateDataTable()
{
int j = 0;
List<string> PL = CreateProcessList();
DataTable DT = new DataTable();
for (int i = 0; i < PL.Count - 2; i += 3)
{
DataRow ProcessRow = DT.NewRow();
DT.Rows[j][0] = PL[i].ToString();
DT.Rows[j][1] = Convert.ToInt32(PL[i + 1]);
DT.Rows[j][2] = Convert.ToInt32(PL[i + 2]);
j++;
}
DT.Columns.Add("Header", typeof(string));
DT.Columns[0].ColumnName = "ProcessName";
DT.Columns[1].ColumnName = "ArrivalTime";
DT.Columns[2].ColumnName = "CpuTime";
return DT;
}
It does not work (says that there is no row at position 0). Thanks for any idea.
Working Code After Editions:
protected DataTable CreateDataTable()
{
List<string> PL = CreateProcessList();
DataTable DT = new DataTable();
DT.Columns.Add("ProcessName", typeof(string));
DT.Columns.Add("ArrivalTime", typeof(int));
DT.Columns.Add("CpuTime", typeof(int));
for (int i = 0; i < PL.Count - 2; i += 3)
{
DataRow ProcessRow = DT.NewRow();
ProcessRow[0] = PL[i].ToString();
ProcessRow[1] = Convert.ToInt32(PL[i + 1]);
ProcessRow[2] = Convert.ToInt32(PL[i + 2]);
DT.Rows.Add(ProcessRow);
}
return DT;
}

To create a datatable in the way you have described, you need to follow a different way.
Create a datatable object
Add Columns to the datatable object by using the Add() method
use the datatable objects NewRow() method to get a DataRow object with the same schema as your datatable
populate the columns of this DataRow with the desired values
Add this DataRow to the Rows collection of your datatable object by using the Add() method
repeat step 3 to 6 until your list reaches the end.

On the second iteration of your for loop i is 3, so you're getting the 4th row of your table (at this point in time your table has 2 row). You're then getting the 4th, 5th, and 6th columns of that row (your table has 0 columns, as you haven't added any columns yet) to set their value. The corresponding index out of range errors should be telling you exactly what's wrong here.
Don't access the i-th row from the table. Just use ProcessRow to access the row; it's right there in a variable for you. Don't access the i-th column, access the 1st, 2nd, and 3rd (and add the columns before you try to populate them.

Something like this should work. Keep adding to curRow until the current iteration starts with 'P'. When it does start with 'P', add the currentRow to the data table and start a new row.
DataTable dataTable;
DataRow curRow;
... add columns to dataTable
for (var i = 0; i < PL.Count; i++) {
if (PL[i].ToString().StartsWith("P")) {
if (curRow != null)
dataTable.Rows.Add(curRow);
curRow = dataTable.NewRow();
}
... add PL[i] to curRow
}
There's a few little issues with this but they can be fixed pretty easily. A check to make sure curRow is not null before adding to data table... that sorta thing.

Related

C# GridView rows added in wrong place?

I want to add rows to my GridView while the function is running.
Before function for adding rows is called there is always 1 "DATA" row present from previous function.
To add rows I tried to use:
int n = grid.Rows.Count;
grid.Rows.Add("Step" + n.ToString());
and I would expect to get rows with labels:
Data...
Step1...
Step2...
Step3...
etc
instead I get:
Step1...
Step2...
Step3...
etc
Data...
(DATA row is pushed to the very bottom, all rows are added above it)
Where is my mistake?
EDIT:
I tried:
int n = grid.Rows.Count;
DataGridViewRow row = new DataGridViewRow();
grid.Rows.Insert(n, row);
grid.Rows[n].Cells[0].Value = "Step"+n.ToString();
but it bugs out.
You can create DataTable and then show it on GridView!
try this:
System.Data.DataTable table = new DataTable();
table.Columns.Add("col1", typeof(string));
table.Columns.Add("col2", typeof(string));
table.Columns.Add("col3", typeof(string));
...
this is creating the rows:
for (int i = 0; i < n - 1; i++)
{
DataRow dr = table.NewRow();
if(i==0)
{
dr[col1]="Data"
dr[col2]= ...
dr[col3]= ...
...
}
if(i>0)
{
// your code
}
table.Rows.Add(dr);
}
to add this table to GridView:
DataView dv1 = new DataView(table);
dataGridView1.DataSource = dv1;
Use Insert to add the records and Count for the last position
Something like:
grid.Rows.Insert(grid.Rows.Count-1, row);

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]);
}

list Values to dataTable

I created a list from an excel document that has partnumbers on the every other starting with the first, and prices on every other row, starting with the second.
Lets say I initialize a datatable like so..
DataTable priceListTable = new DataTable();
priceListTable.Columns.Add("ItemNumber", typeof(string));
priceListTable.Columns.Add("Price", typeof(Float));
And my list (called recordList) looks this;
001-001
1.45
001-002
3.49
How do I get the first two rows of the list to fill the columns of the dataTable?
Here's one solution.
Loop over the list 2 items at a time starting from the 2nd item. This makes sure you always have a pair of items to use.
for (int i = 1; i < list.Count; i += 2)
{
DataRow row = table.NewRow();
row["ItemNumber"] = list[i-1];
row["Price"] = list[i];
table.Rows.Add(row);
}
string ItemNumber = "ItemNumber";
string Price = "Price";
DataTable priceListTable = new DataTable();
DataRow row;
priceListTable.Columns.Add(ItemNumber);
priceListTable.Columns.Add(Price);
int counter = 0;
foreach(string s in recordList)
{
myTableSize++;
}
foreach(string s in recordList)
{
if (counter < myTableSize)
{
row = priceListTable.NewRow();
row[ItemNumber] = recordList[counter];
row[Price] = recordList[counter + 1];
priceListTable.Rows.Add(row);
counter++;
counter++;
}

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.

how to compare 2 datatable and get unique records in 3rd datatable?

I have 2 datatable let say dtData1 and dtData2. I have records in both the datatable I want to compare both the data table and want to create a new datatable let say dtData3 with uniqe records.
suppose: dtData1 has 10 records, and dtData2 has 50 records, but what ever records are there in dtData2 in that 7 records are same as dtData1. So here I want unique records in dtData3, means I want only 43 records in dtData3.
we don't know in datatable where we have the duplicate, and its possible that we will not have duplicates or its also possible that we will have all duplicate records.
So in dtData3 I need unique records
Some one please help me.
var dtData3 = dtData2.AsEnumerable().Except(dtData1.AsEnumerable(), DataRowComparer.Default);
Use this.. Probably it will help you.
Suppose you have two data table
DataTable dt1 = new DataTable();
dt1.Columns.Add("Name");
dt1.Columns.Add("ADD");
DataRow drow;
for (int i = 0; i < 10; i++)
{
drow = dt1.NewRow();
drow[0] = "NameA" + 1;
drow[1] = "Add" + 1;
dt1.Rows.Add();
}
DataTable dt2 = new DataTable();
dt2.Columns.Add("Name");
dt2.Columns.Add("ADD");
DataRow drow1;
for (int i = 0; i < 11; i++)
{
drow1 = dt2.NewRow();
drow1[0] = "Name" + 1;
drow1[1] = "Add" + 1;
dt2.Rows.Add();
}
Now To solve your problem Call :-
DataTable d3 = CompareTwoDataTable(dt1, dt2);
The method is something like this;--
public static DataTable CompareTwoDataTable(DataTable dt1, DataTable dt2)
{
dt1.Merge(dt2);
DataTable d3 = dt2.GetChanges();
return d3;
}
Then where the need to compare dtData1 and dtData2? Instead you can copy the contents from dtData2 to dtData3 starting from index7.
First Create Array variables to save unique coloumn values for datatable3. Use Foreach loop with second gridview rows. If any match then dnt save it in a array value, if dnt match then save it in arrays. and display it by attaching with third gridview.......
e.g
string[] name = new string[4];
int i=0,j=0;
foreach(GridViewRows gv in GridView1.rows)
{
if(gv.Cells[0].Text == GridView2.Rows[i].Cells[0].Text)' //if match
{
// dnt save
}
else' //if dnt match save in array for further use
{
name[j] = gv.Cells[0].Text;
j= j++;
}
i=i++;
}
After Saving unique values in Array "name"...Bind it in Third Gridview
During DataBound of third Gridview add this method...
Private void GridView3_RowDataBound(object sender,EventArgs e)
{
if(e.Row.RowState == DataControlState.DataRow)
{
foreach(string nm in name)
{
e.Rows.Cells.Add(name);
}
}
}
public DataTable CompareTwoDataTable(DataTable dtOriginalTable, DataTable dtNewTable, ArrayList columnNames)
{
DataTable filterTable = new DataTable();
filterTable = dtNewTable.Copy();
string filterCriterial;
if (columnNames.Count > 0)
{
for (int iNewTableRowCount = 0; iNewTableRowCount < dtNewTable.Rows.Count; iNewTableRowCount++)
{
filterCriterial = string.Empty;
foreach (string colName in columnNames.ToArray())
{
filterCriterial += colName.ToString() + "='" + dtNewTable.Rows[iNewTableRowCount][colName].ToString() + "' AND ";
}
filterCriterial = filterCriterial.TrimEnd((" AND ").ToCharArray());
DataRow[] dr = dtOriginalTable.Select(filterCriterial);
if (dr.Length > 0)
{
filterTable.Rows[filterTable.Rows.IndexOf(filterTable.Select(filterCriterial)[0])].Delete();
}
}
}
return filterTable;
}

Categories