Группировка строк данных в VB asp.net 2.0 - PullRequest
3 голосов
/ 12 декабря 2008

Как следует из названия, я пытаюсь сгруппировать строки в таблицу данных. Более подробно эта таблица имеет идентичные строки, за исключением одного поля (столбца). По сути, я пытаюсь поместить все различные поля одинаковых строк и поместить их в одно поле, удаляя другие строки.

Вот синтаксис, который я сейчас использую

   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

Проблема заключается в том, что при удалении строк их индекс изменяется, и в основном поле выбрасывается в другой ряд, который не имеет к этому никакого отношения.

Ответы [ 5 ]

1 голос
/ 12 декабря 2008

Ну, я могу помочь с циклической структурой. Это не совсем соответствует тому, что вы делаете (оно оставляет таблицу нетронутой и просто строит большую строку, а также предполагает, что таблица отсортирована определенным образом), но оно продемонстрирует классическую обработку прерывания управления с использованием ваших реальных данных. Для этого таблица должна быть отсортирована по пользователю, а затем по роли.

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 вложенных циклов, а не только ваши два. Тем не менее, он по-прежнему получает линейную производительность: он будет перебирать каждую запись только один раз. Это работает, потому что все циклы имеют один и тот же счетчик, который увеличивается только во внутреннем цикле, и все они имеют одинаковое условие базового конца.

0 голосов
/ 27 августа 2010

Петлевая часть выглядит так, как будто она закрыта.

Но выборочное (или все) удаление элементов во время цикла может стать неприятным быстро, если вы не понимаете, что хитрость заключается в том, чтобы просто работать снизу вверх (или от последнего элемента до первого или, как вы хотите, чтобы выразить это).

Вот и весь ответ на вопрос об удалении.

Когда вы работаете в последнюю очередь, удаление элемента в нумерованном списке повлияет только на индексы элементов, которые вы уже обработали - и кого это волнует, верно?

-Т.

0 голосов
/ 12 декабря 2008

Ну, видимо, мой код работает. Строка i - = 1 была лишней. Извините за причиненные неудобства и спасибо за помощь

0 голосов
/ 12 декабря 2008

Это довольно сложно прочитать, что обычно означает, что он готов к небольшой реструктуризации.

Можете ли вы описать, чего вы хотите достичь? Что вы хотите оставить в вашей DataTable?

Данные приходят отсортированными или вы можете сделать это в БД? Если он отсортирован, то вам нужен только один цикл.

Я бы сделал следующее:

  • сортировать данные
  • создать новую таблицу данных для ваших результатов
  • шаг по порядку, сохраняя переменную последнего имени пользователя и текущий список ролей. Если имя пользователя не совпадает с последним, добавьте новую строку в таблицу данных с последним именем пользователя и текущим списком ролей. Если имя пользователя совпадает, добавьте его в список ролей. Не забудьте добавить последний ряд, когда дойдете до конца.

Это решает проблему удаления строк из коллекции, через которую вы проходите.

0 голосов
/ 12 декабря 2008

Недавно мне пришлось сделать нечто подобное с отчетом в стиле control-break .

Я прекратил привязку данных к элементу управления повторителя, где шаблон элемента был просто буквальным элементом управления. Затем я обработал событие OnItemDataBound, и у меня был код, который немного напоминал ваш, чтобы проверить, что до тех пор, пока совпадающие столбцы «control» (в смысле разбиения элемента управления, а не в смысле веб-элемента управления) просто добавляют значение оставшегося столбца в класс -уровень переменной и установите e.Item.Visible в false. Когда они больше не совпадают, я оставляю e.Item.Visible как true (по умолчанию) и устанавливаю для свойства Text литерального элемента управления значение html, необходимое для строки, над которой я работал.

Я уверен, что есть лучший способ сделать это, но найти информацию об отчетах о прерываниях управления с помощью asp.net нелегко: слово control имеет двойной смысл при поиске в этом домене, который трудно преодолеть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...