Well, I can help with the loop structure. This does not match what you are doing exactly (it leaves the table intact and just creates a large row, and also assumes the table is sorted in a certain way), but it will demonstrate the classic interrupt handling using your actual data. For this to work, the table must be sorted by the user, and then the role.
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
It has 3 nested loops, not just your two. However, it still gets linear performance: it will only process each record once. It works because all loops have the same counter, which only increases in the inner loop, and they all have the same basic end condition.
source share