Sorting a datatable by a column that contains part numbers and part letters - asp.net

I have a datatable and I need to be able to sort either asc or desc by the jobcode column. Unfortunately the column field values contain both numbers and letters like this.
HD1233
HD12333
PG2839
TP9383
I need to extract the numbers, sort numerically and then put it back. So the above would look like this in the output.
HD1233
PG2839
TP9383
HD12333
I have a piece of code which does some sort of sort which is like this ...
Dim dtOut As DataTable = Nothing
dt.DefaultView.Sort = Convert.ToString("jobcode" & Convert.ToString(" ")) & drpAscorDesc.SelectedItem.Text
dtOut = dt.DefaultView.ToTable()
Im just unable to do it properly without the letters. Any advice would be greatly appreciated.

Add another column of type Integer to your DataTable.
Iterate through all DataRows, put values into new column based on job codes in these datarows (read value -> delete all non-numeric characters -> Int32.TryParse()).
Sort by new column.

Related

Using InStr in Access VBA to lookup a string value from another table

Very new to access VBA and would love some guidance on this.
I am searching through a string and looking for a particular substring in this field. This substring would have a value based on another table, ie
order = "Reference order QQ131415"
The problem is, there is no particular pattern for order numbers. Some are 7 digits, some are 10 and some have dashes in there.
There is a table i have access too that has these order numbers though, and I guess I am trying to use that table as a dictionary.
my very very basic Access VBA code is like this
' order= Instr(1, rst![order], qst![order_id],vbBinaryCompare)'
order is the string where i have the order id i am trying to extract
order_id is the actual id from a seperate table.
Is this something that Access VBA can handle?
So i think this will help you
You're not very clear in the sentence following on from "order=" with your code. Could you clear that up.
Instr(string1, String2, [ compare ])
string1 Required. String expression being searched.
string2 Required. String expression sought.
Instr returns a Variant (number in this case) specifying the position of the first occurrence of one string within another. So it should be:
Position= InStr(1, string1, string2, 1)
So you'd now know that the ordernumber starts at position x in Order. You'd then have to do a left(Order, Len(order) -x) to extract the string.
Youd do that in a nested loop because youll have to loop through your dictionary per record in Order.
E.g.
Dim rsOrder as DAO.recordset
Dim rsOrderId as Dao.recordset
dim orderTest as integer
dim stringcapture as string
Set rsOrder = Currentdb.OpenRecordset("[SELECT STRING]")
rsOrder.Movefirst
Do until rsOrder.EOF or rsOrder.BOF
Order = rsOrder![OrderFieldName]
Set rsOrderId = Currentdb.OpenRecordSet("[SELECT STRING]")
rsOrderID.Movefirst
Do Until rsOrderID.EOF or rsOrderID.BOF
OrderID = rsOrderID![OrderIDFieldName]
orderTest = Instr(1, Order, OrderID,1)
StringCapture = left(Order, Len(order) -OrderTest)
rsOrderID.movenext
Loop
rsOrder.movenext
Loop
rsOrder.close
rsOrderID.close
Something to that affect.

how to get a unqiue result sets in PL/SQL cursor?

I want use this procedure to display the username and moblephone number,the result sets is this when I use select :
declare enter image description here
when the procedure runs,I get this :
enter image description here
error ORA-01722: invalid number
ORA-06512: at "ABPROD.SHAREPOOL", line 24.
when I use unique or distinct in the cursor,nothing display.
the code source :
create or replace procedure sharepool (assignment in varchar2,myorgname in varchar2) is
rightid T_CLM_AP30_RIGHT.RIGHT_ID%type;
orgid t_clm_ap30_org.org_id%type;
begin
select t.right_id into rightid from T_CLM_AP30_RIGHT t where t.rightdesc=trim(assignment);
dbms_output.put_line(rightid||trim(myorgname)||assignment);
select t.org_id into orgid from t_clm_ap30_org t where t.orgname=trim(myorgname);
dbms_output.put_line(orgid);
declare
cursor namelist is select distinct a.username,a.mobile from t_clm_ap30_user a, T_CLM_AP30_RIGHT_AUTH t where a.user_id=t.user_id and t.right_id=rightid and t.poolorgrange=orgid ;
begin
for c in namelist
loop
dbms_output.put_line(c.username||' '||c.mobile);
end loop;
end;
end sharepool;
INVALID_NUMBER errors indicate a failed casting of a string to a number. That means one of your join conditions is comparing a string column with a number column, and you have values in the string column which cannot be cast to a number.
ORA-06512: at "ABPROD.SHAREPOOL", line 24
Line 24 doesn't align with the code you've posted, presumably lost in translation from your actual source. Also you haven't posted table descriptions so we cannot tell which columns to look at.
So here is a guess.
One (or more) of these joins has an implicit numeric conversion:
where a.user_id = t.user_id
and t.right_id = rightid
and t.poolorgrange = orgid
That is, either t_clm_ap30_user.user_id is numeric and T_CLM_AP30_RIGHT_AUTH.user_id is not, or vice versa. Or T_CLM_AP30_RIGHT_AUTH.right_id is numeric and T_CLM_AP30_RIGHT.right_id is not, or vice versa. Or T_CLM_AP30_RIGHT_AUTH.poolorgrange is numeric and t_clm_ap30_org.org_id is not, or vice versa.
Only you can figure this out, because only you can see your schema. Once you have identified the join where you have a string column being compared to a numeric column you need to query that column to find the data which cannot be converted to a number.
Let's say that T_CLM_AP30_RIGHT_AUTH.poolorgrange is the rogue string. You can see which are the troublesome rows with this query:
select * from T_CLM_AP30_RIGHT_AUTH
where translate (poolorgrange, 'x1234567890', 'x') is not null;
The translate() function strips out digits. So anything which is left can't be converted to a number.
"T_CLM_AP30_RIGHT_AUTH.poolorgrange is varchar2,and t_clm_ap30_org.org_id is numeric ."
You can avoid the error by explicitly casting the t_clm_ap30_org.org_id to a string:
select distinct a.username, a.mobile
from t_clm_ap30_user a,
T_CLM_AP30_RIGHT_AUTH t
where a.user_id = t.user_id
and t.right_id = rightid
and t.poolorgrange = to_char(orgid) ;
Obviously you're not going to get matches on those alphanumeric values but the query will run.

Datatable sorting is not working c#

i have a group of values like below pattern
name: color: percentage:
i need to sort this data in desc order of percentage
now i am using data-table DefaultView sort method
//declare columns
DataTable dt = new DataTable();
dt.Columns.Add("name");
dt.Columns.Add("color");
dt.Columns.Add("percentage");
//adding rows
DataRow dr = dt.NewRow();
dr["name"]="a";
dr["color"]="red";
dr["percentage"]="10.1";
dt.Rows.Add(dr);
//sorting
dt.DefaultView.Sort="percentage desc";
the problem is coming when the same number [percentage] is repeating more times
any idea where is the error?
Change this code:
dt.Columns.Add("percentage");
to this:
dt.Columns.Add("percentage", typeof(double));
As multiple people have pointed out, because you added the percentage as a string ("10.1") it's going to be sorted as a string. That means, since you're sorting in descending order, that "2" will appear above "10.1" in your sort. That's because string values are compared character by character, and "2" comes before "1" in a descending alphabetic sort.
Is that the problem you are talking about? If so, either of the other proposed solutions will work for you.
You also said "the problem is coming when the same number [percentage] is repeating more times" If you want a secondary sort column, which affects the order of records with the same primary sort column value (percentage), you have to specify one:
dt.DefaultView.Sort="percentage desc, name asc, color asc";

please help me in creating a sort expressions for datatable in vb.net

I have got a datatable which contains many columns in which three are main:
hotelid
dshotelid
hotelname
Some hotels contain only dshotelid, some contains only hotelid and some contain both dshotelid and hotelid.
I need sort in such way so that those hotels who got both dshotelid and hotelid should be on top and then those hotels who have got only dshotelid and at last those hotels who have got only hotelid...
Please help me to create such a sort expression.
I created this :
dtmaintable.DefaultView.Sort = "dshotelid, hotelid"
but it Is not giving me desired output.
Fields with NULL in them tend to appear at the top of sorted columns (unless the sort is in descending order) so you're probably seeing rows with both hotelid and dshotelid at the bottom, instead of the top?
How is this data table populated? If it's coming from a database query, it's a simple matter to construct an additional column (or columns) which contain(s) whatever sort key you need - be it an amalgum of other columns or some other unique identifier.
EDIT: Feb 4, 2010 - in response to your 'FilterAndSortTable' solution:
Your solution works but it's not because of the FilterAndSortTable - it's because you used a different sort order.
Originally, you used "dsohtelid, hotelid".
The second time, you used "dshotelid desc, hotelid desc".
This has the effect of putting your non-nulls at the top and nulls at the bottom, but I would dispute that this qualifies as a good solution.
Your id's are now sorted backwards - which I kind of assumed you might want to avoid, hence my suggestion of a new sort column that would respect this.
Still, if the order of id's doesn't matter then your solution is fine and you can simply stick with your original code, with the addition of 'desc', like so:
dtmaintable.DefaultView.Sort = "dshotelid desc, hotelid desc"
Of course, if anything I've said here has been of any use to you, a tick would be muchly appreciated. It would help me reach 50 rep points and finally be able to write comments. :)
i got the answer its :
datagrid1.datasource = FilterandSortTable(dtmaintable,"", "dshotelid desc, hotelid desc")
Public Shared Function FilterandSortTable(ByVal SourceTable As DataTable, ByVal strFilters As String, Optional ByVal strOrder As String = "") As DataTable
Dim Tbl As DataTable = SourceTable.Clone
Dim rows() As DataRow = SourceTable.Select(strFilters, strOrder)
For i As Integer = 0 To rows.Length - 1
Tbl.ImportRow(rows(i))
Next
Return Tbl
End Function

Datatable Compute Function for multiple columns

I want to count the number of non-null values per column in a Datatable. I could loop through the columns and use the compute function on each column, but I was wondering if there is a more efficient way to do this.
You could add a column with an expression that checks whether the rests of the columns are null, see http://msdn.microsoft.com/en-us/library/system.data.datacolumn.expression(VS.80).aspx
Then you can Compute on that column.
I think that the Compute function is quite appropriate in this context. You could use code similar to the following:
For Each col as DataColumn in myTable
Dim aggExpr as string = string.format("Count{0}", col.ColumnName)
Dim filterExpr as string = string.format("{0} IS NULL", col.ColumnName)
Dim myCount as integer = CInt(myTable.Compute(aggExpr, filterExpr))
Console.WriteLine(myCount)
Next
(Typed in here, watch for syntax)
Note that I say "similar to the following". Please add appropriate error/null value checks.

Resources