I have two DataTables that have the same columns. I would like to append one of these DataTables on to the end of the other and then sort them by date. What is the best way of going about this?
When I try to merge and sort them, like this:
private DataTable mergeAndSortTables(DataTable manualTable, DataTable gpsTable)
{
manualTable.Merge(gpsTable);
manualTable.DefaultView.Sort = "Date DESC";
return manualTable.DefaultView.ToTable();
}
I still end up with rows out of order. What am I doing wrong?
Edit: I also get the exact same results with this code:
private DataTable mergeAndSortTables(DataTable manualTable, DataTable gpsTable)
{
manualTable.Merge(gpsTable);
DataView view = manualTable.DefaultView;
view.Sort = "Date DESC";
return view.ToTable();
}
Instead of modifying the default view, create a new view based upon the current table an sort that. This should fix your issue.
You have to assigne the dataview and then work on it.
DefaultView view = manualTable.DefaultView;
view.Sort = "Date DESC";
return view.ToTable();
I think the problem might be that Date is a keyword - try ...
manualTable.DefaultView.Sort = "[Date] DESC";
You can use DataTable.Select() method for sorting although it will return you the DataRow[]. For example, after merging, you can do DataRow[] rows = manualTable.Select("", columnName sortOrder). You can always convert this DataRow[] to another table and return it.
Related
I want to sort a DataTable within a DataSet. I have the following code:
DataTable dt = ds.Tables[0];
dt.TableName = "NEWNAME";
dt.DefaultView.ApplyDefaultSort = false;
dt.DefaultView.Sort = "COL1 desc";
dt = dt.DefaultView.ToTable();
dt.AcceptChanges(); // <-- Break Point Here
ds.AcceptChanges();
As I step through the code beyond the break point in Visual Studio, checking on dt in VS visualizer shows the sorted table, but then checking on ds in VS visualiser does not show the table data in sorted order, even though the name change is reflected. I have tried multiple ways of sorting the datatable available in a google search but the outcome remains the same.
What am I doing wrong?
DefaultView.Sort doesn't sort anything. It is just a string that will be used when you require the construction of a new table like you do in the line
dt = dt.DefaultView.ToTable();
after this point the dt reference (correctly sorted with the info taken from DefaultView.Sort) is no more pointing to the ds.Tables[0]. It is an entirely new DataTable.
The other way in which the DefaultView.Sort applies is when you loop through the DefaultView like in
foreach(DataViewRow dvr in ds.Tables[0].DefaultView)
{
// Here you get a row from the table sorted according to the property.
DataRow row = dvr.Row;
.....
}
One DataSet usually has lots of DataTable, but I'm only to target a particular DataTable which I thought it's pretty normal but apparently failed to do it?
Below were the approaches I've tried:
//Could not find an implementation of the query pattern for source type.......
DataTable dt = from table in changesDataSet.Tables
where table.TableName = "ABC"
select table;
//Surprisingly there was no method "Where" in changesDataSet.Tables
DataTable dt = changesDataSet.Tables.Where(x=>x.TableName="ABC").First();
Below was the code that able to print each and every table. I know I can do it via a loop but please tell me loop isn't the only options
foreach(DataTable table in changesDataSet.Tables)
{
Console.WriteLine(table.TableName);
}
You can access the table using an indexer on the collection of tables (DataTableCollection):
DataTable dt = changesDataSet.Tables["ABC"];
I have a DataGridView which I have used RowFilter on it like following:
(dgv.DataSource as DataTable).DefaultView.RowFilter = whereClause;
Before applying the RowFilter the DataGridView has 1087 records and afterwards, it has about 8.
Now I want to work on those 8 records.
How can I access them?
If you do
dgv.DataSource as DataTable
Then you can do the following
dataTable dt = dgv.DataSource as DataTable;
DataRow[] rows = dt.Select("your filter goes here");
You can do same thing by Linq if you want to. These are your rows and you can work with them. And to Edit only these records do:
DataGridView.DataSource = rows;
Also, you can create a custom DataView, which will filter records the way you want it, and set datasource to that view. But remember, the key here, no matter how many views you have - this is same dataTable that you looking at
DataView view = new DataView();
view.Table = dt;
view.RowFilter = "your filter";
view.Sort = "your sort";
You can use DataGridViewRow.DataBoundItem to access to the underlying data.
If your DataGridView bound to the DataView the underlying data is of type DataRowView. You can use code like this:
var dataRow = dgv.Rows[rowIndex].DataBoundItem as DataRowView;
I have a DataView with Sort applied on it. I am not able to assign/copy the Sorted State of DataView to DataTable.
Sort the DataView with Column 'Distance':
DataTable table=GetData();
DataView view = table.DefaultView;
view.Sort = "Distance";
this works fine.
But, when i assign this DataView to DataTable it *LOOSES THE SORTED STATE*.
DataTable dt = (view.Table);
This looses the Sorted State of DataView
Any idea?
Please correct my code if something wrong.
So, i want to assign/copy the Sorted DataView to DataTable without loosing the Sorted State.
Use view.ToTable() instead of view.Table. Please see below snippet
DataTable table=GetData();
DataView view = table.DefaultView;
view.Sort = "Distance";
DataTable dt = view.ToTable();
You can directly get dataview propery in the Datatable itself.
DataTable table=GetData();
table.DefaultView.Sort="Distance";
table=table.DefaultView.ToTable();
Here's a really efficient way to write a one line sort that maintains the sorting of the DataView in the parent DataTable.
table = new DataView(table, "", "Distance",
DataViewRowState.CurrentRows).ToTable()
I need to sort a DataTable or DataGridView by a column that is a string value, but with null/empty values at the BOTTOM when sorting ASCENDING.
The DataTable is NOT populated by a SQL statement, so no order by.
If I do
DataGridView1.Sort(New RowComparer(System.ComponentModel.ListSortDirection.Ascending))
then it throws an exception, saying that the DataGridView is DataBound, which is correct, but doesn't help me, and I want to keep it databound.
It's .NET 2.0, which means no LINQ available!
in some cases you could do this if you have another extra column in your table:
SELECT completed, completed IS NULL AS isnull
FROM TABLE
ORDER BY isnull DESC, completed DESC
Edit:
Like this in VB.NET
For Each srSearchResult In srcSearchResultCollection
Try
dr = dt.NewRow()
dr("cn") = srSearchResult.GetDirectoryEntry().Properties("cn").Value
dr("Account") = srSearchResult.GetDirectoryEntry().Properties("sAMAccountName").Value
dr("Nachname") = srSearchResult.GetDirectoryEntry().Properties("sn").Value
dr("Vorname") = srSearchResult.GetDirectoryEntry().Properties("givenname").Value
dr("Mail") = srSearchResult.GetDirectoryEntry().Properties("mail").Value
dr("HomeDirectory") = srSearchResult.GetDirectoryEntry().Properties("homedirectory").Value
dr("LogonScript") = srSearchResult.GetDirectoryEntry().Properties("scriptPath").Value
dr("IsNull") = String.IsNullOrEmpty(dr("Nachname").ToString())
dt.Rows.Add(dr)
Catch ex As Exception
End Try
Next srSearchResult
dt.DefaultView.Sort = "IsNull ASC, Nachname ASC"
Davide Piras has a good solution, however there is another simplest solution I have
Add a new column and do it in just one line
// just, add a new column
ActualDataTable.Columns.Add("NullEmptyCheck", typeof(int), "ColumnNameToSort is Null OR ColumnNameToSort = ''");
// apply sort expression
ActualDataTable.DefaultView.Sort = "NullEmptyCheck asc, ColumnNameToSort asc";
// pass datasource to grid
MyGridView.DataSource = ActualDataTable.DefaultView;
MyGridView.DataBind();
even if the DataTable you bind to the user interface control DataGridView is not populated via SQL, you can still sort it using a DataView, you can do something like this:
DataView myView = myDataTable.DefaultView;
myView,Sort = "yourColumnName ASC";
then you do your binding.
how does it work? Are the null values in the top or in the bottom?
For those who are looking for a way to achieve this in .NET 4+, here is a example :
DataTable orderedDataTable = sourceDataTable.AsEnumerable()
.OrderByDescending(row => !string.IsNullOrWhiteSpace(row.Field<string>("COLUMN_NAME")))
.ThenBy(row => row.Field<string>("COLUMN_NAME"))
.CopyToDataTable();
This will place null values at the end of the table (note that both empty and white spaces strings will have the same rank) and then order the requested column in ascending order.