2008-12-12 5 views
3

Comme son nom l'indique, j'essaie de regrouper des lignes dans une datatable. Pour aller plus loin, cette table a des lignes identiques à l'exception d'un champ (colonne). Fondamentalement, ce que j'essaie de faire est de mettre tous les différents champs des lignes identiques et les mettre dans un champ unique tout en supprimant les autres lignes.Regroupement de lignes d'une datable dans VB asp.net 2.0

Voici la syntaxe que je suis actuellement en utilisant

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 

Le problème est lorsque vous supprimez les lignes de leurs index change et essentiellement le champ est jeté dans une autre ligne qui n'a rien à voir avec elle.

Répondre

1

Eh bien, je peux aider avec la structure en boucle. Cela ne correspond pas à ce que vous faites exactement (il laisse la table intacte et construit simplement une grande chaîne, et suppose également que la table est triée d'une manière particulière), mais il montrera le traitement classique de rupture de contrôle en utilisant vos données réelles. Pour que cela fonctionne, la table doit être triée par utilisateur puis par rôle.

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 

Cela a boucles imbriquées, plutôt que vos deux.Cependant, il obtient toujours des performances linéaires: il ne va parcourir qu'une seule fois chaque enregistrement. Cela fonctionne parce que toutes les boucles partagent le même compteur, qui n'est incrémenté que dans la boucle interne, et toutes ont la même condition de fin de base.

+0

Cheers mate vérifiera plus tard – Drahcir

0

J'ai dû faire quelque chose de similaire récemment avec un rapport de style control-break.

J'ai terminé la liaison des données à un contrôle de répéteur où le modèle d'élément était juste un contrôle littéral. Puis j'ai traité l'événement OnItemDataBound et j'ai eu un code qui ressemblait vaguement au vôtre pour vérifier que tant que les colonnes "control" (dans le sens du contrôle-rupture plutôt que dans le sens du contrôle web) correspondent, ajoutez juste la valeur de la colonne restante à une classe -level variable et définissez e.Item.Visible sur false. Quand ils ne correspondent plus, je laisse e.Item.Visible comme true (par défaut) et définissez la propriété Text du contrôle littéral sur le html requis pour la ligne sur laquelle je travaillais. Je suis sûr qu'il y a une meilleure façon de le faire, mais il n'est pas facile de trouver des informations sur les rapports de rupture de contrôle avec asp.net: le mot control a un double sens lors de la recherche dans ce domaine qui est difficile à surmonter .

+0

Notez que je n'aime vraiment pas la façon dont j'ai fait le code, c'est-à-dire que c'est une boucle imbriquée qui absorbe beaucoup de performance. Je pensais que peut-être il y avait une solution plus simple à cela – Drahcir

0

C'est assez difficile à lire, ce qui signifie généralement qu'il est prêt à être restructuré.

Pouvez-vous décrire plus ce que vous voulez réaliser? Que voulez-vous rester dans votre DataTable?

Est-ce que les données sont triées ou pouvez-vous le faire dans la base de données? Si le tri est effectué, il vous suffit de faire une seule boucle.

Je ferais ce qui suit:

  • sorte datatable
  • faire une nouvelle datatable pour vos résultats
  • étape par dans l'ordre, en gardant une variable du dernier nom d'utilisateur et la liste actuelle des les rôles. Si le nom d'utilisateur n'est pas le même que le dernier, ajoutez une nouvelle ligne à votre datatable avec le dernier nom d'utilisateur et la liste actuelle des rôles. Si le nom d'utilisateur est le même, ajoutez-le à la liste des rôles. Ne pas oublier d'ajouter la dernière rangée quand vous arrivez à la fin.

Cela contourne le problème de la suppression des lignes de la collection que vous parcourez.

+0

va télécharger un diagramme de ce que je veux atteindre, mais je suis actuellement au travail et ne peut pas parcourir les sites d'hébergement d'images. – Drahcir

0

Eh bien apparemment, mon code fonctionne. La ligne i - = 1 était extra. Désolé pour tout inconvénient causé et merci pour l'aide

+0

Si les données sont triées, vérifiez mon code. Il profite du tri pour obtenir des performances linéaires plutôt que n au carré ou n log (n). –

0

La partie en boucle a l'air d'être recouverte. Mais la suppression d'éléments sélectivement (ou tous) en boucle peut devenir méchante rapidement si vous ne réalisez pas que l'astuce consiste simplement à travailler depuis le bas (ou du dernier élément au premier, ou vous voulez l'exprimer).

Voilà toute la réponse pour la partie des suppressions de la question. Lorsque vous travaillez du dernier au dernier, la suppression d'un élément dans une liste numérotée affectera uniquement les index des éléments que vous avez déjà traités - et qui s'en soucie alors, n'est-ce pas?

-T.