How find datarows and change index of datarow in an existing datatable? - c#

I have an existing DataTable with thousand rows and want to find the rows and set it to become top rows.

I don't know if you're able to, but I would probably add a dummy column to sort by, give the rows you want a higher value in the dummy column, and then sort by the column from bigger to smaller with a DataView.
private void ModifyTable(DataTable toModify)
{ //Add a column to sort by later.
DataColumn col = toModify.Columns.Add("DummySort", typeof(int));
col.DefaultValue = 0;
}
private void SetDummyColumnValue(DataRow dr, int value)
{ //Mark the columns you want to sort to bring to the top.
//Give values bigger than 0!
dr["DummySort"] = value;
}
private DataTable GetSortedTable(DataTable modifiedTable)
{
//Sort by the column from bigger to smaller
DataView dv = new DataView(modifiedTable);
dv.Sort = "DummySort DESC"; return dv.ToTable();
}

You can try to remove and insert row
public void MoveDataRowTo(DataRow dataRow,int destination)
{
DataTable parentTable = dataRow.Table;
int rowIndex = parentTable.Rows.IndexOf(dataRow);
if (rowIndex > 0)
{
DataRow newDataRow = parentTable.NewRow();
for (int index = 0; index < dataRow.ItemArray.Length; index++)
newDataRow[index] = dataRow[index];
parentTable.Rows.Remove(dataRow);
parentTable.Rows.InsertAt(newDataRow, destination);
dataRow = newDataRow;
}
}

DataSet dsAct = new DataSet();
OleDbDataAdapter odaTem = new OleDbDataAdapter("SELECT ActivityId, Activity FROM tbl_Activity", ocnConn);
odaTem.Fill(dsAct, "Activity");
DataRow drTem;
int i = 0;
//Rows want set to be on top is in the table "TopActivity"
foreach (DataRow dr in dsAct.Tables["TopActivity"].Rows)
{
drTem = dsAct.Tables["Activity"].NewRow();
//Clone the row
drTem.ItemArray = dsAct.Tables["Activity"].Rows.Find(dr["Activity_ID"]).ItemArray;
dsAct.Tables["Activity"].Rows.RemoveAt( dsAct.Tables["Activity"].Rows.IndexOf( dsAct.Tables["Activity"].Rows.Find(dr["Activity_ID"])));
dsAct.Tables["Activity"].Rows.InsertAt(drTem, i);
i++;
}

Related

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

select certain columns of a data table

I have a datatable and would like to know if its possible for me to select certain columns and input the data on a table. the columns are set out as below
|col1 |col2 |col3|col4 |col5 |col6|col7 |col8 |col9 |col10 |col11 |
I want to select column col1, col2 col6, col7,col3. and dispay the data in a gridview of the rows within the datatable.. currently the code that i am using is below and onmly selects certain data. I am not selecting the data from sql its data being selected from another excel which is stored in a datatable.. but i am in need of the other columns in another area as well.. this data is being written into a table in word
for (int i = 1; i < table.Rows.Count; i++)
{
for (int j = 0; j < table.Columns.Count; j++)
{
if (j == 0)
{
val = filteredData.Rows[row][col].ToString();
}
else
{
val = filteredData.Rows[row][col].ToString();
if (val == "-" || val == "")
{
val = filteredData.Rows[row][col].ToString();
}
else
{
val = Convert.ToString(Math.Round(Convert.ToDouble(filteredData.Rows[row][col]), MidpointRounding.AwayFromZero));
}
}
table[j, i].TextFrame.Text = val;
col++;
}
Also we can try like this,
string[] selectedColumns = new[] { "Column1","Column2"};
DataTable dt= new DataView(fromDataTable).ToTable(false, selectedColumns);
First store the table in a view, then select columns from that view into a new table.
// Create a table with abitrary columns for use with the example
System.Data.DataTable table = new System.Data.DataTable();
for (int i = 1; i <= 11; i++)
table.Columns.Add("col" + i.ToString());
// Load the table with contrived data
for (int i = 0; i < 100; i++)
{
System.Data.DataRow row = table.NewRow();
for (int j = 0; j < 11; j++)
row[j] = i.ToString() + ", " + j.ToString();
table.Rows.Add(row);
}
// Create the DataView of the DataTable
System.Data.DataView view = new System.Data.DataView(table);
// Create a new DataTable from the DataView with just the columns desired - and in the order desired
System.Data.DataTable selected = view.ToTable("Selected", false, "col1", "col2", "col6", "col7", "col3");
Used the sample data to test this method I found:
Create ADO.NET DataView showing only selected Columns
The question I would ask is, why are you including the extra columns in your DataTable if they aren't required?
Maybe you should modify your SQL select statement so that it is looking at the specific criteria you are looking for as you are populating your DataTable.
You could also use LINQ to query your DataTable as Enumerable and create a List Object that represents only certain columns.
Other than that, hide the DataGridView Columns that you don't require.
Here's working example with anonymous output record, if you have any questions place a comment below:                    
public partial class Form1 : Form
{
DataTable table;
public Form1()
{
InitializeComponent();
#region TestData
table = new DataTable();
table.Clear();
for (int i = 1; i < 12; ++i)
table.Columns.Add("Col" + i);
for (int rowIndex = 0; rowIndex < 5; ++rowIndex)
{
DataRow row = table.NewRow();
for (int i = 0; i < table.Columns.Count; ++i)
row[i] = String.Format("row:{0},col:{1}", rowIndex, i);
table.Rows.Add(row);
}
#endregion
bind();
}
public void bind()
{
var filtered = from t in table.AsEnumerable()
select new
{
col1 = t.Field<string>(0),//column of index 0 = "Col1"
col2 = t.Field<string>(1),//column of index 1 = "Col2"
col3 = t.Field<string>(5),//column of index 5 = "Col6"
col4 = t.Field<string>(6),//column of index 6 = "Col7"
col5 = t.Field<string>(4),//column of index 4 = "Col3"
};
filteredData.AutoGenerateColumns = true;
filteredData.DataSource = filtered.ToList();
}
}
You can create a method that looks like this:
public static DataTable SelectedColumns(DataTable RecordDT_, string col1, string col2)
{
DataTable TempTable = RecordDT_;
System.Data.DataView view = new System.Data.DataView(TempTable);
System.Data.DataTable selected = view.ToTable("Selected", false, col1, col2);
return selected;
}
You can return as many columns as possible.. just add the columns as call parameters as shown below:
public DataTable SelectedColumns(DataTable RecordDT_, string col1, string col2,string col3,...)
and also add the parameters to this line:
System.Data.DataTable selected = view.ToTable("Selected", false,col1, col2,col3,...);
Then simply implement the function as:
DataTable myselectedColumnTable=SelectedColumns(OriginalTable,"Col1","Col2",...);
Thanks...
DataView dv = new DataView(Your DataTable);
DataTable dt = dv.ToTable(true, "Your Specific Column Name");
The dt contains only selected column values.

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

Copy Data Table to a Data Grid without binding them together

I have two datagrids in my application (dataGridView1 and dataGridView2). I am moving selected items from dataGridView1 into dataGridView2. Here is how I am currently doing this:
DataTable dt = new DataTable("dt");
DataTable id = new DataTable("id");
try
{
if (dataGridView1.Rows.Count > 0)
{
for (int i = 0; i < dataGridView1.Rows.Count - 0; i++)
{
if (dataGridView1.Rows[i].Cells[0].Value != null)
{
DataRow row;
DataRow idRow;
row = dt.NewRow();
idRow = id.NewRow();
idRow["id"] = dataGridView1.Rows[i].Cells[1].Value.ToString();
row["id"] = dataGridView1.Rows[i].Cells[1].Value.ToString();
row["Link Name"] = dataGridView1.Rows[i].Cells[2].Value.ToString();
dt.Rows.Add(row);
id.Rows.Add(idRow);
}
}
dataGridView2.DataSource = dt;
}
However, I also need to be able to remove items from dataGridView2. Currently, the DataTable dt is bound to dataGridView2 and I cant clear it after the items are added because it also clears the dataGridView2.
Basicly, my question would be, is there a way to add the contents of a data table to a data grid without using datagrid.DataSource?
You can manually add each row using the dataGridView2.Rows.Add function. Also, I have typically used the dataGridView2.Row(n).Tag to hold the actual source of that row's data.
int n = dataGridView2.Rows.Add();
DataGridViewRow newRow = dataGridView2.Rows[n];
newRow.Cells[0].Value = "ABC";
newRow.Cells[1].Value = 123;
newRow.Tag = row;

Categories