3

顾名思义,我正在尝试对数据表中的行进行分组。更详细地说,该表具有相同的行,除了一个字段(列)。基本上我要做的是将相同行的所有不同字段放入单个字段中,同时删除其他行。

这是我目前使用的语法

   Dim i As Integer
    Dim j As Integer
    For i = 0 To (ds.Tables(0).Rows.Count() - 1) Step 1
        If (i < ds.Tables(0).Rows.Count()) Then
            roleHtml = "<table><tr><td>" + ds.Tables(0).Rows(i).Item("roleName") + "</td></tr>"
            For j = (ds.Tables(0).Rows.Count() - 1) To 0 Step -1
                If (ds.Tables(0).Rows(i).Item("UserName") = ds.Tables(0).Rows(j).Item("UserName")) And (ds.Tables(0).Rows(i).Item("roleName") IsNot ds.Tables(0).Rows(j).Item("roleName")) Then
                    roleHtml += "<tr><td>" + ds.Tables(0).Rows(j).Item("roleName") + "</td></tr>"
                    ds.Tables(0).Rows.Remove(ds.Tables(0).Rows(j))
                    i -= 1
                End If
            Next j
            roleHtml += "</table>"
            ds.Tables(0).Rows(i).Item("roleName") = roleHtml
        End If
    Next i

问题是当删除行时,他们的索引发生了变化,基本上该字段被扔到与它无关的另一行中。

4

5 回答 5

1

好吧,我可以帮助处理循环结构。这与您正在做的事情不完全匹配(它使表格完好无损,只是构建了一个大字符串,并且还假设表格以特定方式排序),但它将使用您的实际数据演示经典的控制中断处理。为此,表需要按用户排序,然后按角色排序。

Dim i As Integer = 0
Dim CurUser As String = ""
Dim CurRole As String = ""
Dim result As new StringBuilder()
Dim r as DataRowCollection = ds.Tables(0).Rows

While i < r.Count
    'Next User:'
    CurUser = r(i)("UserName")
    result.AppendFormat("<h2>{0}</h2>", CurUser).AppendLine()
    result.AppendLine("<table>")

    While i < r.Count AndAlso CurUser = r(i)("UserName")
        'Next Role:'
        CurRole = r(i)("roleName")
        result.AppendFormat("<tr><td>{0}</td></tr>", CurRole).AppendLine()

        While i < r.Count AndAlso CurUser = r(i)("UserName") AndAlso CurRole = r(i)("roleName")
            i += 1 'Next Record: same user, role '
        End While
        'Finished this role'
    End While
    'Finished this user:'
     result.AppendLine("</table>").AppendLine()
End While

这有3 个嵌套循环,而不仅仅是你的两个。然而,它仍然获得线性性能:它只会遍历每条记录一次。它之所以有效,是因为所有循环共享相同的计数器,该计数器仅在内部循环中递增,并且它们都具有相同的基本结束条件。

于 2008-12-12T16:45:31.253 回答
0

最近我不得不用控制中断风格的报告 做类似的事情。

我结束了将数据绑定到一个转发器控件,其中项目模板只是一个文字控件。然后我处理了 OnItemDataBound 事件,并使用与您的代码有点相似的代码来检查,只要“控制”(在控制中断意义上而不是 Web 控制意义上)列匹配,只需将剩余列的值添加到一个类-level 变量并将 e.Item.Visible 设置为 false。当它们不再匹配时,我将 e.Item.Visible 保留为 true(默认)并将文字控件的 Text 属性设置为我正在处理的行所需的 html。

我确信有更好的方法来做到这一点,但是使用 asp.net 查找控制中断报告的信息并不容易:control在这个难以克服的域中搜索时,这个词具有双重含义。

于 2008-12-12T15:44:12.843 回答
0

这很难阅读,这通常意味着它已经准备好进行一些重组。

您能详细说明您想要实现的目标吗?你想在你的数据表中留下什么?

数据是否已排序,或者您可以在数据库中进行排序吗?如果它已排序,那么您只需要一个循环即可。

我会做以下事情:

  • 对数据表进行排序
  • 为您的结果创建一个新的数据表
  • 按顺序单步执行,保留最后一个用户名和当前角色列表的变量。如果用户名与最后一个不同,则使用最后一个用户名和当前角色列表向您的数据表添加一个新行。如果用户名相同,则附加到角色列表。到最后不要忘记添加最后一行。

这解决了从您正在单步执行的集合中删除行的问题。

于 2008-12-12T16:08:35.120 回答
0

显然我的代码有效。i -=1 行是额外的。很抱歉给您带来不便,感谢您的帮助

于 2008-12-12T17:04:06.490 回答
0

循环部分看起来像是被覆盖了。

但是,如果您没有意识到诀窍是从下往上(或从最后一个元素到第一个元素,或者您想表达它),那么在循环时选择性地(或全部)删除项目可能会很快变得讨厌.

这就是问题删除部分的全部答案。

当您从最后一个到第一个工作时,删除编号列表中的项目只会影响您已经处理的项目的索引 - 那谁在乎,对吧?

-T。

于 2010-08-27T13:44:04.430 回答