Add range rows from one DataTable to another - c#

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.

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

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

C# DataTable delete row

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

Converting a List into Datatable

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.

Categories