Dataview Rowfilter - c#

I have a textbox and a button. What i am attempting to do is filter a gridview with the data that has been searched for. The two fields im searching for are customerID and CustomerName.
My code:
Dim GetAllCusts As New BusinessLayer.Customer
Dim dt As DataTable = GetAllCusts.GetCustomers
Dim dv As New DataView(dt)
dv.RowFilter = String.Format("CustomerID='{0}' Or CustomerName='{0}'", SearchTextbox.Text)
gridview1.DataSource = dv
gridview1.DataBind()
When searching for a customer id everything works. When searching for a customer name i get "Cannot perform '=' operation on System.Int32 and System.String.".
I tried to CONVERT(CustomerName, System.String) but that didnt resolve however i think this was leading me away from the initial problem as i started to guess around.
I would like to have one textbox to search for a customer id and customer name. What is wrong with the RowFilter and how could it be resolved?
Thanks

You have a conceptual problem. Or you search for a number or you search for a string.
I think you should change your code in this way
Dim custID as Integer
if Int32.TryParse(SearchTextbox.Text, custID) Then
' CustomerID is a numeric field - no need to use single quotes'
dv.RowFilter = String.Format("CustomerID={0}", custID)
else
' CustomerName is a string. Use single quotes and double the '
' possible single quotes inside the search box'
dv.RowFilter = String.Format("CustomerName='{0}'", SearchTextbox.Text.Replace("'", "''")
End If
gridview1.DataSource = dv

I guess CutomerId is a integer field and when you try to search for a Name which is a string field you are trying to search an integer field with a string value.

Related

How to filter Data table

I want to filter data table based on some condition .
I have a data table like that
Tabel A
MobileNo Email
9999999999 test#test1.com
8888888888 test#test2.com
9999999999 test#test5.com
7777777777 test#test6.com
I want to get distinct value based on mobile also I need data that not exits in distinct table but table A have
Like
Distinct Table Ignore Table
MobileNo Email MobileNo Email
9999999999 test#test1.com 9999999999 test#test5.com
8888888888 test#test2.com
7777777777 test#test6.com
I have also tried googling but that are not very much understandable.
Thanks in Advance
You can use the select method on DataTable
Dim dtFiltered As New DataTable()
dtFiltered = dtAllData.DefaultView.ToTable(True, "MobileNo")
dtAllData is the DataTable containing all records
dtFiltered contains only Distinct Records
For more details check MSDN article
UPDATE based on your comment
In that case you need to use except as in
datatable-comparison-using-linq-except-intersect-union
From all records extract distinct records to second DataTable and then use Except to compare the first and second DataTable
Thanks for all your help
Finally I got the solution
Dim ValidData = (From row In tbValid.AsEnumerable()
Let Mobile = row.Field(Of String)("Mobile")
Group row By Mobile Into DupMobile = Group
Select DupMobile.First).ToArray
Dim Ignoredata = tbValid.AsEnumerable().Except(ValidData.AsEnumerable(), DataRowComparer.Default).ToArray
From your example all you have done is order your mobile no. in desending order which means you could then create a SQL to say something like: ORDER BY MobileNo DESC at the end of the statement. At least it will display the same way
Or are you meaning:
Dim dv As DataView = New DataView(DataTable.DataView)
dv.RowFilter = "%" &...

Sort and Search Datatable

I have a datatable that has been bound to a Gridview in code behind. This means i would have to sort columns in code behind and when searching for a record i would imagine that would be done in code behind too.
The code i have to sort the gridview is
Private Function GetCustData As Datatable
Dim dt as new datatable
dt = GetDataFromBusinessLayer(CustomerID)
Return dt
End Function
And the code to sort
Private Sub gv_Sorting(sender As Object, e As System.Web.UI.WebControls.GridViewSortEventArgs) Handles gv.Sorting
If e.SortExpression = "Name"
gv.DataSource = GetCustData '.DefaultView.Sort = "Name" & "DESC"
gv.DataBind()
End If
End Sub
As you can tell i tried using .DefaultView.Sort = "Name" & "DESC" but this didnt work and got the error Data source is an invalid type. It must be either an IListSource, IEnumerable, or IDataSource. Searching around most are using Viewstate but that doesnt seem applicable in my case.
Can anyone advise how i would sort one/multiple columns?
In addition i will like to have a textbox which will search for the Name column. I think the above should suffice when it comes to it but if not could someone put me on the right track so i can work towards that now rather than having to change what im doing at a later stage?
First of all, your current code does not have a space. To sort by Name DESC your Sort string would need to be: "Name DESC".
To set the Sort string to multiple columns, just add a comma between each one, like this:
Dim dt as new datatable = GetCustData(1)
dt.DefaultView.Sort = "Name DESC, FirstName ASC"
gv.DataSource = dt.DefaultView
gv.DataBind()
I think you can create a list of rows
List<DataRow> list = dt.AsEnumerable().ToList();
and then when you have a list you can now use sort
list.OrederBy(c=>c.///specific value in your list)
What about using Linq to do the sort for you.
Dim dt as new datatable
dt = From dr as Datarow in GetDataFromBusinessLayer(CustomerID)
Order by dr.item("First Sort field), dr.Item("Second Sort Field")
Select dr
Return dt
... I did this without the IDE, but that should do the trick, I believe.
Here's one exmaple online - Sorting DataTable with Linq
Hope this helps.

Sort dataGridView columns in C# ? (Windows Form)

I have a datagridview that i bind from an sql table, in that dv i have those attributes: Id, Name and Price. When i set the SortMode of the Name Columns to Automatic and i click on the header of this column i can sort this dv based on the first letter of the Name, this way i can order products based on their first letters ( Acumulator, Boat, CocaCola, Engine etc).
Is there a way this thing to happen without clicking the header of the column Name. I am looking some code that will do this job when the form will load.
There's a method on the DataGridView called "Sort":
this.dataGridView1.Sort(this.dataGridView1.Columns["Name"], ListSortDirection.Ascending);
This will programmatically sort your datagridview.
dataGridView1.Sort(dataGridView1.Columns[0],ListSortDirection.Ascending);
This one is simplier :)
dataview dataview1;
this.dataview1= dataset.tables[0].defaultview;
this.dataview1.sort = "[ColumnName] ASC, [ColumnName] DESC";
this.datagridview.datasource = dataview1;
You can control the data returned from SQL database by ordering the data returned:
orderby [Name]
If you execute the SQL query from your application, order the data returned. For example, make a function that calls the procedure or executes the SQL and give it a parameter that gets the orderby criteria. Because if you ordered the data returned from database it will consume time but order it since it's executed as you say that you want it to be ordered not from the UI you want it to be ordered in the run time so order it when executing the SQL query.
The best way to do this is to sort the list before binding data source.
cars = cars.OrderBy(o => o.year).ThenBy(o => o.color).ToList();
adgCars.DataSource = cars;
Sorry for my bad english.
Use Datatable.Default.Sort property and then bind it to the datagridview.
I know 2 solutions to this problem.
1. Sort (DataGridViewColumn column, ListSortDirection direction) function
This function can be used to sort a column alphabetically or numerically or by date in descending or ascending order.
example:
dataGridView.Sort(dataGridView1.Columns[5],ListSortDirection.Ascending);
2. Sort (IComparer comparer) function
This function can be use for all other situations as
Sorting a column with specific order that is different than numeric order (example: sorting an amount that can be negative or positive using only absolute values)
Sorting a column with specific order that is different than alphabetic order (example: sorting a text using case insensitive sort)
Sorting multiples columns as sorting a table using AMOUNT column as first column and DATE column as second column.
VB.Net example:
Private Sub pbSort_Click(sender As Object, e As EventArgs) _
Handles pbSort.Click
grid.Sort(New AmountDateComparer(Me))
End Sub
Private Class AmountDateComparer : Implements IComparer
Private frm As FrmSearch
Public Sub New(frm As FrmSearch)
Me.frm = frm
End Sub
Public Function Compare(x1 As Object, x2 As Object) As Integer _
Implements IComparer.Compare
Dim row1 As DataGridViewRow = x1
Dim row2 As DataGridViewRow = x2
' compare AMOUNT values of columns
Dim nAmount1 = Convert.ToDecimal(row1.Cells(frm.Col_AMOUNT.Index).Value)
Dim nAmount2 = Convert.ToDecimal(row2.Cells(frm.Col_AMOUNT.Index).Value)
Dim iCompareResult As Integer
= System.Decimal.Compare(nAmount1, nAmount2)
If iCompareResult = 0 Then
'compare DATE values of columns
Dim d1 = Convert.ToDateTime(row1.Cells(frm.Col_DATE.Index).Value)
Dim d2 = Convert.ToDateTime(row2.Cells(frm.Col_DATE.Index).Value)
iCompareResult = System.DateTime.Compare(d1, d2)
End If
Return iCompareResult
End Function
End Class

SELECT DISTINCT in DataView's RowFilter

I'm trying to narrow down the rows that are in my DataView based on a relation with another table, and the RowFilter I'm using is as follows;
dv = new DataView(myDS.myTable,
"id IN (SELECT DISTINCT parentID FROM myOtherTable)",
"name asc",
DataViewRowState.CurrentRows);
"myTable" and "myOther" table are related via myTable.ID and myOtherTable.parentID, and so the idea is that the DataView should only contain rows from "myTable" which have corresponding child rows in "myOtherTable".
Unfortunately, I'm getting this error;
Syntax error: Missing operand after
'DISTINCT' operator.
The SQL is fine as far as I am aware, so I'm wondering is there some limitation on using the DISTINCT keyword as part of RowFilter's SQL? Anyone have any idea?
Unfortunately, I don't think you can perform a subquery in a DataView's filter expression. You're only allowed to use a subset of SQL in some expressions (documented here).
You'll probably need to perform your subquery (SELECT DISTINCT parentID FROM myOtherTable) separately.
This article describes the problem and a possible solution.
Unfortunately you can't do it that way, as the RowFilter property does not support the distinct keyword. Here is the list of expressions you can perform in a RowFilter (which is just a DataColumn Expression): http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression.aspx
DataViews have a ToTable method, and several overloads take a boolean to specify whether to return only the distinct rows.
Here is one method: http://msdn.microsoft.com/en-us/library/wec2b2e6.aspx
Here is how you would use it:
DataTable newDataTable = myDataView.ToTable( true, [array of column names as strings] );
DataView dvBindAssignedByDropDown = new DataView();
DataTable dtBindAssignedByDropDown = new DataTable();
dvBindAssignedByDropDown = ds.Tables[0].DefaultView;
string[] strColnames=new string[2];
strColnames[0] = "RedNames";
strColnames[1] = "RedValues";
dtBindAssignedByDropDown = dvBindAssignedByDropDown.ToTable(true, strColnames);
ddlAssignedby.DataTextField = "RedNamesNames";
ddlAssignedby.DataValueField = "RedNames";
ddlAssignedby.DataSource = dtBindAssignedByDropDown;
ddlAssignedby.DataBind();
ddlAssignedby.Items.Insert(0, "Assigned By");
ddlAssignedby.Items[0].Value = "0";
the following code is extracting distinct values/records from a table/dataview, namely(PROD_DESP_TRN) having field(CONTAINER_NO)
Finally, this code is filling a combobox(cmbContainerNo) with unique values/records
Form Level Declaration:
Dim dsLocal As DataSet
Dim dvm As DataViewManager
Private Sub FillcomboContainer()
Try
Dim dv As DataView = New DataView
cmbContainerNo.DataSource = Nothing
dv = dvm.CreateDataView(dsLocal.Tables("PROD_DESP_TRN"))
dv.Sort = "CONTAINER_NO"
cmbContainerNo.DataSource = dv.ToTable(True, "CONTAINER_NO")
cmbContainerNo.DisplayMember = "CONTAINER_NO"
Catch ex As Exception
MsgBox(ex.Message)
Finally
End Try
End Sub
Try just leaving out the "DISTINCT". In this case, the results should be the same with or without. Troubleshoot from there.

How to get a value from a column in a DataView?

I have a dataview defined as:
DataView dvPricing = historicalPricing.GetAuctionData().DefaultView;
This is what I have tried, but it returns the name, not the value in the column:
dvPricing.ToTable().Columns["GrossPerPop"].ToString();
You need to specify the row for which you want to get the value. I would probably be more along the lines of table.Rows[index]["GrossPerPop"].ToString()
You need to use a DataRow to get a value; values exist in the data, not the column headers. In LINQ, there is an extension method that might help:
string val = table.Rows[rowIndex].Field<string>("GrossPerPop");
or without LINQ:
string val = (string)table.Rows[rowIndex]["GrossPerPop"];
(assuming the data is a string... if not, use ToString())
If you have a DataView rather than a DataTable, then the same works with a DataRowView:
string val = (string)view[rowIndex]["GrossPerPop"];
#Marc Gravell ....
Your answer actually has the answer of this question.
You can access the data from data view as below
string val = (string)DataView[RowIndex][column index or column name in double quotes] ;
// or
string val = DataView[RowIndex][column index or column name in double quotes].toString();
// (I didn't want to opt for boxing / unboxing) Correct me if I have misunderstood.
for anyone in vb.NET:
Dim dv As DataView = yourDatatable.DefaultView
dv.RowFilter ="query " 'ex: "parentid = 1 "
for a in dv
dim str = a("YourColumName") 'for retrive data
next

Categories