I want to remove equal entries from DataTable.
I tried DefaultView, but it only removes the equals and not all entries which including them.
DataView view = table1.DefaultView;
DataTable tbl = view.ToTable();
return tbl;
you can do this
public DataTable RemoveDuplicate(DataTable dataTable, string columname)
{
Hashtable hashTable = new Hashtable();
List<String> duplicates = new List<String>();
foreach (DataRow datarow in dataTable.Rows)
{
if (hashTable .Contains(datarow [columname]))
{
duplicateList.Add(datarow );
}
else
{
hashTable .Add(datarow [columname], string.Empty);
}
}
//Now remove the duplicates .
foreach (DataRow datarow in duplicates )
dataTable.Rows.Remove(datarow );
return dataTable;
}
Related
The code below choose the first row and remove the other row below with specific id. The things that i want is the last line within the id.
var dtremove = RemoveDuplicateRows(dt, "id);
This the extension
public DataTable RemoveDuplicateRows(DataTable dt, string colName)
{
Hashtable hTable = new Hashtable();
ArrayList duplicateList = new ArrayList();
//Add list of all the unique item value to hashtable, which stores combination of key, value pair.
//And add duplicate item value in arraylist.
foreach (DataRow drow in dt.Rows)
{
if (hTable.Contains(drow[colName]))
{
duplicateList.Add(drow);
}
else
hTable.Add(drow[colName], string.Empty);
}
//duplicateList.Sort();
//Removing a list of duplicate items from datatable.
foreach (DataRow dRow in duplicateList)
dt.Rows.Remove(dRow);
//Datatable which contains unique records will be return as output.
return dt;
}
The example of datatable.
id date
------------
A 1/1/2018
A 1/2/2018
A 1/3/2018
B 2/1/2018
B 2/2/2018
i want the result like this.
id date
------------
A 1/3/2018
B 2/2/2018
I tried not to change too much of your code, pretty sure it can be improved, but the changes below looks for the value and if it already exists in the dictionary, it replaces it: Thus, you will end up with the very last row instead of the first one. Also, it returns a new DataTable and the original one will stay intact.
public DataTable RemoveDuplicateRows(DataTable dt, string colName)
{
var uniqueRows = new Dictionary<string, DataRow>();
foreach (DataRow thisRrow in dt.Rows)
{
if (uniqueRows.ContainsKey(colName))
{
uniqueRows[colName] = thisRrow;
}
else
{
uniqueRows.Add(colName, thisRrow);
}
}
DataTable copy = dt.Copy();
copy.Rows.Clear();
foreach (var thisRow in uniqueRows)
{
copy.Rows.Add(thisRow.Value);
}
//Datatable which contains unique records will be return as output.
return copy;
}
I have datatable on which I have to perform filter like where, order by. I have list of customerName. I want to filter data for each customername
I tried below code for same
foreach (string customer in CustName)
{
Datarow[] DataDR = TradeFinanceBF3.Select(TradeFinanceBF3.Columns["Cust_Name"].ColumnName.Trim() + "='A'", "USD equi DESC");
}
I get datarow, then how to pass it to dataTable, and how to pass all customer data to same datatable.
I tried LinkQuery Also to filter data as below
foreach (string customer in CustName)
{
DataTable selectedTable = TradeFinanceBF3.AsEnumerable()
.Where(r => r.Field<string>("Cust_Name") == customer)
.OrderByDescending(r => r.Field<double>("IndexABC"))
.CopyToDataTable();
///Datable OutPut= ?????
}
I got datatable, But then how to add all customer data to one datatable?
You could do something like this:
DataRow[] result = TradeFinanceBF3.Select("Cust_Name ='A'", "USD equi DESC");
DataTable aux = TradeFinanceBF3.Clone();
foreach (DataRow record in result)
{
aux.ImportRow(record);
}
I hope it will fix your issue
[Test]
public void GetCustomerData()
{
DataTable TradeFinanceBF3 = GetTable();
DataTable NewDatatable = TradeFinanceBF3.Clone();
IList<string> CustName = new List<string> { "Janet", "David" };
var selectedTable = (from dataRow in TradeFinanceBF3.AsEnumerable()
join customerName in CustName on dataRow.Field<string>("Cust_Name") equals customerName
select new
{
CustName = dataRow["Cust_Name"],
IndexABC = dataRow["IndexABC"]
}).OrderByDescending(p=>p.IndexABC);
foreach (var table in selectedTable)
{
NewDatatable.Rows.Add(table.CustName, table.IndexABC);
}
Console.Write(NewDatatable);
}
private DataTable GetTable()
{
// Here we create a DataTable with four columns.
DataTable table = new DataTable();
table.Columns.Add("Cust_Name", typeof(string));
table.Columns.Add("IndexABC", typeof(double));
// Here we add five DataRows.
table.Rows.Add("David", 1);
table.Rows.Add("Sam", 2);
table.Rows.Add("Christoff",2);
table.Rows.Add("Janet", 4);
table.Rows.Add("Melanie", 6);
return table;
}
I have a dataset ds and a List of ArrayList newpath i want to add(assign) ds to newpath
how is that possible.
public List<ArrayList> newpath
{
set { ViewState["newpath"] = value; }
get
{
if (ViewState["newpath"] == null)
return new List<ArrayList>();
else
return (List<ArrayList>)ViewState["newpath"];
}
}
i am trying with
foreach (DataRow dataRow in Ftb.Rows)//Ftb is datatable
{
newpath.Add(dataRow);//newpath is List<ArrayList>
}
and
foreach (DataRow dRow in ds.Tables[0].Rows)
{
newpath.Add(dRow);
}
if i am doing like above way then i am getting the error
"The best overloaded method match for 'System.Collections.Generic.List.Add(System.Collections.ArrayList)' has some invalid arguments"
Please help me if in someway.. how to do that
I assume you want each item in newpath to contain the column values of each row?
If so, have such code instead:
foreach (DataRow dataRow in Ftb.Rows)//Ftb is datatable
{
ArrayList values = new ArrayList();
foreach (object value in dataRow.ItemArray)
values.Add(value);
newpath.Add(values);
}
change newpath from
List<ArrayList>
to
List<DataRow>
From the code you've posted it looks as if your newpath variable is a list of ArrayLists. So when you try to add dRow which is DataRow you're getting an error as it's not an ArrayList.
If you want to add DataRows I think newpath should be a list of DataRow. If you wanted to populate the ArrayList with data from the DataRow you'd need something like this -
foreach (DataRow dataRow in Ftb.Rows)//Ftb is datatable
{
ArrayList myAL = new ArrayList();
myAL.Add(dataRow["your_column_name"]);
//add fields from DataRow to array list using your required logic
newpath.Add(myAL);
}
I have modified #Shadow Wizard code and now its working fine
List<ArrayList> newval = new List<ArrayList>();
foreach (DataRow dRow in ds.Tables[0].Rows)
{
ArrayList values = new ArrayList();
foreach (object value in dRow.ItemArray)
values.Add(value);
newval.Add(values);
}
newpath = newval;
I may well be looking at this problem backwards but I am curious none the less. Is there a way to build a DataTable from what is currently displayed in the DataGridView?
To be clear, I know you can do this DataTable data = (DataTable)(dgvMyMembers.DataSource); however that includes hidden columns. I would like to build it from the displayed columns only.
Hope that makes sense.
So I ended up trying a combination of a couple of answers as that seemed best. Below is what I am trying. Basically I am creating the DataTable from the DataSource and then working backwards based on if a column is visible or not. However, after it removes a column I get a Collection was modified; enumeration operation may not execute on the next iteration of the foreach.
I am confused as I am not trying to modify the DataGridView, only the DataTable so what's up?
DataTable data = GetDataTableFromDGV(dgvMyMembers);
private DataTable GetDataTableFromDGV(DataGridView dgv)
{
var dt = ((DataTable)dgv.DataSource).Copy();
foreach (DataGridViewColumn column in dgv.Columns)
{
if (!column.Visible)
{
dt.Columns.Remove(column.Name);
}
}
return dt;
}
Well, you can do
DataTable data = (DataTable)(dgvMyMembers.DataSource);
and then use
data.Columns.Remove(...);
I think it's the fastest way. This will modify data source table, if you don't want it, then copy of table is reqired. Also be aware that DataGridView.DataSource is not necessarily of DataTable type.
I don't know anything provided by the Framework (beyond what you want to avoid) that would do what you want but (as I suspect you know) it would be pretty easy to create something simple yourself:
private DataTable GetDataTableFromDGV(DataGridView dgv) {
var dt = new DataTable();
foreach (DataGridViewColumn column in dgv.Columns) {
if (column.Visible) {
// You could potentially name the column based on the DGV column name (beware of dupes)
// or assign a type based on the data type of the data bound to this DGV column.
dt.Columns.Add();
}
}
object[] cellValues = new object[dgv.Columns.Count];
foreach (DataGridViewRow row in dgv.Rows) {
for (int i = 0; i < row.Cells.Count; i++) {
cellValues[i] = row.Cells[i].Value;
}
dt.Rows.Add(cellValues);
}
return dt;
}
one of best solution enjoyed it ;)
public DataTable GetContentAsDataTable(bool IgnoreHideColumns=false)
{
try
{
if (dgv.ColumnCount == 0) return null;
DataTable dtSource = new DataTable();
foreach (DataGridViewColumn col in dgv.Columns)
{
if (IgnoreHideColumns & !col.Visible) continue;
if (col.Name == string.Empty) continue;
dtSource.Columns.Add(col.Name, col.ValueType);
dtSource.Columns[col.Name].Caption = col.HeaderText;
}
if (dtSource.Columns.Count == 0) return null;
foreach (DataGridViewRow row in dgv.Rows)
{
DataRow drNewRow = dtSource.NewRow();
foreach (DataColumn col in dtSource .Columns)
{
drNewRow[col.ColumnName] = row.Cells[col.ColumnName].Value;
}
dtSource.Rows.Add(drNewRow);
}
return dtSource;
}
catch { return null; }
}
First convert you datagridview's data to List, then convert List to DataTable
public static DataTable ToDataTable<T>( this List<T> list) where T : class {
Type type = typeof(T);
var ps = type.GetProperties ( );
var cols = from p in ps
select new DataColumn ( p.Name , p.PropertyType );
DataTable dt = new DataTable();
dt.Columns.AddRange(cols.ToArray());
list.ForEach ( (l) => {
List<object> objs = new List<object>();
objs.AddRange ( ps.Select ( p => p.GetValue ( l , null ) ) );
dt.Rows.Add ( objs.ToArray ( ) );
} );
return dt;
}
I have a row collection (DataRow[] rows). And I want to import all rows to another DataTable (DataTable dt).
But how?
Code
DataTable dt;
if (drs.Length>0)
{
dt = new DataTable();
foreach (DataRow row in drs)
{
dt.Columns.Add(row???????)
}
// If it possible, something like that => dt.Columns.AddRange(????????)
for(int i = 0; i < drs.Length; i++)
{
dt.ImportRow(drs[i]);
}
}
Assuming the rows all have the same structure, the easiest option is to clone the old table, omitting the data:
DataTable dt = drs[0].Table.Clone();
Alternatively, something like:
foreach(DataColumn col in drs[0].Table.Columns)
{
dt.Columns.Add(col.ColumnName, col.DataType, col.Expression);
}
If your DataRows is from a Data Table with Columns defined in it,
DataRow[] rows;
DataTable table = new DataTable();
var columns = rows[0].Table.Columns;
table.Columns.AddRange(columns.Cast<DataColumn>().ToArray());
foreach (var row in rows)
{
table.Rows.Add(row.ItemArray);
}
How about
DataTable dt = new DataTable;
foreach(DataRow dr in drs)
{
dt.ImportRow(dr);
}
Note this only works if drs is a DataRowCollection. Detached rows (not in a DataRowCollection are ignored).
Don't forget to call AcceptChanges.
Try this:
// Assuming you have a DataRow object named row:
foreach(DataColumn col in row.Table.Columns)
{
// Do whatever you need to with these columns
}