2013-04-25 139 views
1

我有这样的:如何根据数据行子串对VB.NET DataView进行排序?

Dim strS As String = "" 
Dim strRowFilter As String = "SID=" & strSID 
Dim dv As DataView = objDataSet.Tables(1).DefaultView 
dv.RowFilter = (strRowFilter) 
dv.Sort = ("RIGHT(SName, CHARINDEX(' ', REVERSE(' ' + RTRIM(SName))) - 1)") 
For Each objDataRow As DataRow In dv 
      'build strS 
     Next 

Return strS 

SName是格式Firstname Midname Lastname(Midname可选)的字符串,我需要通过Lastname进行排序。我知道有一些特殊情况,比如'麦克圣克劳德',但对于最后一句话的排序,我很好。上面的代码给我System.IndexOutOfRangeException occurred: Cannot find column RIGHT(SName.

我得到排序术语this,它在SQL Server中作为ORDER BY。我对此深感不满,所以任何帮助将不胜感激。

+0

这不是'ArrayList',它是'DataView'。 – 2013-04-25 17:36:26

+0

好点,编辑。我通过编写问题中途改变了战术。道歉。 – 2013-04-25 17:37:48

+0

我以为你已经问过类似这个问题[这里](http:// stackoverflow。COM /问题/ 15934925 /何灿的i-排序的 - 内容 - Telerik的-gridboundcolumn为主,在-A-子)。你不能应用我给你的同样的方法吗? – ajakblackgoat 2013-04-25 18:26:12

回答

1

根据该MSDN,所述Sort属性是:

包含列名,后跟 “ASC”(升序)或 “DESC”(降序)的字符串。列按默认顺序升序排列。多列可以用逗号分隔。

因为,一些在System.Data命名空间中的类允许使用类似于SQL的语法有些东西(如DataTable.Select法),人们常常感到困惑,以为所有的SQL语法支持。事实并非如此。在这种情况下,Sort属性支持非常狭窄的功能。它只能设置为一个或多个列名称(以及ASCDESC订单说明符)。它不支持RIGHTLEFT等功能。

如果您确实想使用DataView进行排序,则可以在包含要对视图进行排序的字符串的数据中添加一个附加列。当您将数据选入DataSet时,可以使用所有这些SQL字符串操作方法构建排序字符串以选择该排序列。

但是,除非您确实需要这样做,否则我会建议只创建一个ArrayList数据,然后对其进行排序。当你这样做时,你可以访问.NET的所有字符串操作方法,这些方法功能更强大,更易于阅读。例如:

Dim names As New List(Of String)() 
For Each row As DataRow In objDataSet.Tables(1).Rows 
    names.Add(CStr(row("SName"))) 
Next 
names.Sort(Function(x, y) x.Split().Last.CompareTo(y.Split().Last)) 
+0

太感谢了,这做到了! – 2013-05-31 14:10:30

1

试试这个:

Dim strS As String = "" 
Dim dt As DataTable = objDataSet.Tables(1) 

' create a lambda expression to split the name by " " 
Dim splitName = Function(name As String) name.Split(" "c).Where(Function(s) s <> "") 

' select rows that meet the SID filter and SName <> null and SName <> "", 
' and get the SID, construct the FirstName and LastName, 
' and of course, sort the return collection by LastName 
Dim sortedrows = From row As DataRow In dt.Rows 
       Where (Not IsDBNull(row!SName) AndAlso Not String.IsNullOrWhiteSpace(CStr(row!SName))) 
       And CStr(row!SID) = strSID 
       Select PersonID = row!PersonID, 
       FirstName = splitName(CStr(row!SName)).FirstOrDefault, 
       LastName = splitName(CStr(row!SName)).LastOrDefault 
       Order By LastName 

' finally, construct the <a> tags as required from above 
For Each row In sortedrows 
    strS &= String.Format("<a href=""javascript: ViewPersonId({0}); return false;"">{1} {2}</a><br />", row.PersonID, row.FirstName, row.LastName) 
Next 

如果DataTable包含以下行:

dt.Rows.Add(1, "John Travolta") 
dt.Rows.Add(2, "Jack The Ripper") 
dt.Rows.Add(3, "Beyonce") 
dt.Rows.Add(4, " ") 
dt.Rows.Add(5, "") 
dt.Rows.Add(6, DBNull.Value) 

比方说,他们都满足了SID过滤器,它会返回:

<a href="javascript: ViewPersonId(3); return false;">Beyonce Beyonce</a><br /> 
<a href="javascript: ViewPersonId(2); return false;">Jack Ripper</a><br /> 
<a href="javascript: ViewPersonId(1); return false;">John Travolta</a><br /> 

就像你可以看到,"Beyonce"显示为"Beyonce Beyonce"。如果您不想要这种行为,可以通过检查For Each循环中的FirstName = LastName并执行替代代码来构造<a>标记来更改它。

+0

谢谢。上述方法对我来说是最合适的,但我有一个类似的问题,我认为我可以解决这个问题。非常感激。 – 2013-05-31 14:12:26

相关问题