IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

traitement datagridview trop long


Sujet :

VB.NET

  1. #1
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Novembre 2008
    Messages : 123
    Points : 83
    Points
    83
    Par défaut traitement datagridview trop long
    Bonjour,

    je charge dans un DGV le contenu d'un fichier texte de 891 lignes.
    Ensuite, j'effectue un traitement par groupe de 3 lignes : j'applique différentes conditions de couleurs et de mise en forme sur les cellules de la première ligne en fonction du contenu de la seconde

    Le temps de chargement est trop long principalement à cause de la boucle ci-dessous qui dure 15 secondes (sur 18). Que puis-je faire pour accélérer ce traitement ? Peut-on le faire en arrière plan ? Merci


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
     
     
    'cette boucle dure 15s
    For i As Integer = 0 To DGV1.RowCount - 1 Step 3 'la première ligne d'une réf est identique à celle des manquants sans confirmation
     
                    DGV1.Rows(i).Height = 40
                    DGV1.Rows(i + 1).Visible = False  'je masque cette ligne, seulement utile à la mise en forme de la ligne "i", inutile de l'afficher dans le dgv.
                    DGV1.Rows(i + 2).DefaultCellStyle.BackColor = Color.Gray
                    DGV1.Rows(i + 2).Height = 30
     
    'cette partie dure 12s
                    For j As Integer = 15 To DGV1.Columns.Count - 1
                        If DGV1.Rows(i).Cells(j).Value < 0 And DGV1.Rows(i + 1).Cells(j).Value < 0 Then
                            DGV1.Rows(i).Cells(j).Style.BackColor = Color.OrangeRed
                            DGV1.Rows(i).Cells(j).Style.ForeColor = Color.White
                        ElseIf DGV1.Rows(i).Cells(j).Value < 0 And DGV1.Rows(i + 1).Cells(j).Value > 0 Then 'en fonction du contenu de la 2e ligne, on modifie la couleur de ces cellules de la premiere
                            DGV1.Rows(i).Cells(j).Style.BackColor = Color.OliveDrab
     
                        Else
     
                            DGV1.Rows(i).Cells(j).Style.BackColor = Color.LightGreen
                        End If
     
                        DGV1.Rows(i + 2).Cells(j).Style.BackColor = Color.White  'coloration de la 3e ligne à partir de la colonne 15
                        If (DGV1.Rows(i + 2).Cells(j).Value <> "0 / 0") Then
                            DGV1.Rows(i + 2).Cells(j).Style.ForeColor = Color.Blue
                        Else
                            DGV1.Rows(i + 2).Cells(j).Style.ForeColor = Color.Gray
                        End If
     
                    Next
     
    'cette partie dure 3s
                    For j As Integer = 4 To 13
                        DGV1.Rows(i + 2).Cells(j).Style.BackColor = Color.Black
                        DGV1.Rows(i + 2).Cells(j).Style.ForeColor = Color.White
                        DGV1.Rows(i + 2).Cells(j).Value = "" 'on vide la cellule
                        DGV1.Rows(i + 2).Cells(j).ReadOnly = True
                    Next
                    DGV1.Rows(i + 2).Cells(DGV1.Columns.Count - 1).Value = ""   'je vide le contenu de la dernière cellule de la ligne.
    next
    Jérémy

  2. #2
    Membre éprouvé
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Octobre 2006
    Messages
    691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Octobre 2006
    Messages : 691
    Points : 996
    Points
    996
    Par défaut
    Bonjour,

    Juste quelques remarques.
    1) As tu tenté de faire un visible=false sur la DatagGridView avant le début du chargement et de le repasser à true après le remplissage ? Les actions sur le style ou le redimensionnement (ton height) appellent d'autres évènements, et le ré-affichage complet à chaque modif, ce qui peut prendre du temps (si la DataGridView est affichée, d'où l'intérêt de la masquer temporairement).
    2) As tu des évènements traités sur la DataGridView qui s'activeraient lors du changement d'une cellule ? Ils pourraient être fautifs.

  3. #3
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Novembre 2008
    Messages : 123
    Points : 83
    Points
    83
    Par défaut
    bonjour,

    non, j'ai cherché du côté de screenupdating, héritage de mes années vba, sans penser tout simplement à cette propriété (dgv1.visible=false)
    merci.

    Jérémy
    Jérémy

  4. #4
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Novembre 2008
    Messages : 123
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par m4k-Hurrican Voir le message
    Bonjour,

    Juste quelques remarques.
    1) As tu tenté de faire un visible=false sur la DatagGridView avant le début du chargement et de le repasser à true après le remplissage ? Les actions sur le style ou le redimensionnement (ton height) appellent d'autres évènements, et le ré-affichage complet à chaque modif, ce qui peut prendre du temps (si la DataGridView est affichée, d'où l'intérêt de la masquer temporairement).
    2) As tu des évènements traités sur la DataGridView qui s'activeraient lors du changement d'une cellule ? Ils pourraient être fautifs.
    Bonjour, j'ai testé :
    1) visible = false n'a pas eu d'impact sur le temps de traitement.
    2) j'ai un événement dans la DGV qui s'active lors du changement de valeur d'une cellule. mais ça ne joue que si on modifie 2 cellules particulières de la ligne. Or je n'y touche pas à ce moment là.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
       Private Sub DGV1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DGV1.CellValueChanged
     
            If (e.ColumnIndex = 8 Or e.ColumnIndex = 7) Then
     
                Dim jourJ As Date
                jourJ = FormatDateTime(DateTime.Now.Date)
                ' ajout de la date de mise à jour
                DGV1.CurrentRow.Cells(9).Value = jourJ.ToString("dd/MM/yyyy")
                DGV1.CurrentRow.Cells(DGV1.Columns.Count - 1).Value = "x"  'cette valeur va permettre, lors de la sauvegarde, d'exclure les lignes non modifiées
                commentaireChanged = True '1 commentaire a été changé, les commentaires doivent donc pouvoir être sauvegardés
     
            End If
        End Sub
    3) comme tu me parlais du redimensionnement, j'ai testé leur durée.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
     
    For i As Integer = 0 To DGV1.RowCount - 1 Step 3 'la première ligne d'une réf est identique à celle des manquants sans confirmation
     
    'ces 2 redimensionnements durent 7s 
                    DGV1.Rows(i).Height = 40
                  DGV1.Rows(i + 2).Height = 30
     
    'cacher cette ligne dure 6s
      DGV1.Rows(i + 1).Visible = False  'je masque cette ligne, seulement utile à la mise en forme de la ligne "i", inutile de l'afficher dans le dgv.
     
    ....
    Donc de 17s initialement, je descends à 4s, ce qui est largement mieux, mais reste beaucoup pour si peu de lignes.
    Si je peux facilement résoudre la question des dimensions, j'ai toujours besoin de masquer la ligne. ou le mieux est de la supprimer ?
    Jérémy

  5. #5
    Modérateur
    Avatar de ProgElecT
    Homme Profil pro
    Retraité
    Inscrit en
    Décembre 2004
    Messages
    6 077
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 68
    Localisation : France, Haute Savoie (Rhône Alpes)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Décembre 2004
    Messages : 6 077
    Points : 17 185
    Points
    17 185
    Par défaut
    Salut

    Le fait de ne pas faire faire un rafraichissement de l'affichage de l'écran à chaque modification d'une cellule peut être une solution valable, plutôt que de rendre invisible le DGV , de mon temps, j'avais un meilleur résultat en déplaçant le DGV hors de l'écran.
    DGV.Left = -DGV .Width durant le chargement/modification des données, puis rétablissement du .left quand fini.
    Soyez sympa, pensez -y
    Balises[CODE]...[/CODE]
    Balises[CODE=NomDuLangage]...[/CODE] quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Balises[C]...[/C] code intégré dans une phrase.
    Balises[C=NomDuLangage]...[/C] code intégré dans une phrase quand vous mettez du code d'un autre langage que celui du forum ou vous postez.
    Le bouton en fin de discussion, quand vous avez obtenu l'aide attendue.
    ......... et pourquoi pas, pour remercier, un pour celui/ceux qui vous ont dépannés.
    👉 → → Ma page perso sur DVP ← ← 👈

  6. #6
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Novembre 2008
    Messages : 123
    Points : 83
    Points
    83
    Par défaut
    Salut, merci pour la proposition. Mais elle n'a aucun effet d'accélération sur le temps de traitement des mises en forme.
    je désespère. faudrait-il passer tout cela dans la mémoire de la machine ?
    Jérémy

  7. #7
    Membre éprouvé
    Homme Profil pro
    Responsable de service informatique
    Inscrit en
    Octobre 2006
    Messages
    691
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Jura (Franche Comté)

    Informations professionnelles :
    Activité : Responsable de service informatique
    Secteur : Distribution

    Informations forums :
    Inscription : Octobre 2006
    Messages : 691
    Points : 996
    Points
    996
    Par défaut
    Citation Envoyé par jerem7w Voir le message
    2) j'ai un événement dans la DGV qui s'active lors du changement de valeur d'une cellule. mais ça ne joue que si on modifie 2 cellules particulières de la ligne. Or je n'y touche pas à ce moment là.
    A moins que j'ai mal lu, tu modifies bien le contenu des cellules 7 et 8 dans ta boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                    For j As Integer = 4 To 13
                        DGV1.Rows(i + 2).Cells(j).Style.BackColor = Color.Black
                        DGV1.Rows(i + 2).Cells(j).Style.ForeColor = Color.White
                        DGV1.Rows(i + 2).Cells(j).Value = "" 'on vide la cellule
                        DGV1.Rows(i + 2).Cells(j).ReadOnly = True
                    Next
    A voir combien de temps l'activation de l'évènement te fais perdre dans la boucle.

  8. #8
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Novembre 2008
    Messages : 123
    Points : 83
    Points
    83
    Par défaut
    Citation Envoyé par m4k-Hurrican Voir le message
    A moins que j'ai mal lu, tu modifies bien le contenu des cellules 7 et 8 dans ta boucle :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
                    For j As Integer = 4 To 13
                        DGV1.Rows(i + 2).Cells(j).Style.BackColor = Color.Black
                        DGV1.Rows(i + 2).Cells(j).Style.ForeColor = Color.White
                        DGV1.Rows(i + 2).Cells(j).Value = "" 'on vide la cellule
                        DGV1.Rows(i + 2).Cells(j).ReadOnly = True
                    Next
    A voir combien de temps l'activation de l'évènement te fais perdre dans la boucle.
    Oui, mais l'événement ne porte que sur un changement de la valeur, voici le code.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
        Private Sub DGV1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DGV1.CellValueChanged
     
            If (e.ColumnIndex = 8 Or e.ColumnIndex = 7) Then
     
                Dim jourJ As Date
                jourJ = FormatDateTime(DateTime.Now.Date)
                ' ajout de la date de mise à jour
                DGV1.CurrentRow.Cells(9).Value = jourJ.ToString("dd/MM/yyyy")
                DGV1.CurrentRow.Cells(DGV1.Columns.Count - 1).Value = "x"  'cette valeur va permettre, lors de la sauvegarde, d'exclure les lignes non modifiées
                commentaireChanged = True '1 commentaire a été changé, les commentaires doivent donc pouvoir être sauvegardés
     
            End If
        End Sub
    Même si j'enlève cet évenement du DGV, cela ne réduit pas le temps de traitement.
    Jérémy

  9. #9
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Bonjour,

    Il y a dans ton code, une anomalie de nature à perdre du temps ...

    Cette anomalie est celle qui consiste à modifier la valeur d'une cellule du DGV à l'intérieur de la procédure événementielle de réponse à un changement de valeur d'une cellule de ce DGV :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        Private Sub DGV1_CellValueChanged(sender As Object, e As DataGridViewCellEventArgs) Handles DGV1.CellValueChanged
    ' ... ... ...
                DGV1.CurrentRow.Cells(9).Value = jourJ.ToString("dd/MM/yyyy")
    ' ... ... ... 
            End If
    Il en est de mêlme ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
                    For j As Integer = 4 To 13
    ' ... ... ...
                        DGV1.Rows(i + 2).Cells(j).Value = "" 'on vide la cellule !!! VIDER c'est aussi CHANGED ...
    ' ... ... ...
                    Next
    m4k-Hurrican a déjà soulevé ce problème. Etonnant que ça ne plante pas ...
    Peut-être devrais-tu reconsidérer tout ton algorithme.

    J'espère que ceci t'aidera.

    Bonne journée ...

  10. #10
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour

    Comme dit par Phil , il suffit de faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
    ' avant  de rentrer  dans  ta boucle
    RemoveHandler   DGV1_CellValueChanged, AddressOF DGV1_CellValueChanged
     
    ' plus  loin après sortie de ta boucle
     
    ' 
    AddHandler   DGV1_CellValueChanged, AddressOF DGV1_CellValueChanged
    bon code...

  11. #11
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    ... et ne pas oublier le AddHandler avant de quitter ...

  12. #12
    Membre régulier
    Profil pro
    Inscrit en
    Novembre 2008
    Messages
    123
    Détails du profil
    Informations personnelles :
    Âge : 47
    Localisation : France, Calvados (Basse Normandie)

    Informations forums :
    Inscription : Novembre 2008
    Messages : 123
    Points : 83
    Points
    83
    Par défaut
    bonjour

    désolé, je viens seulement d'appliquer vos conseils et cela m'a résolu un problème, mais pas celui pour lequel j'avais créé ce post : le temps de traitement. merci quand même

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
     '  avant  de rentrer  dans  la boucle, on désactive l'événement qui porte sur la modification du DGV1
            RemoveHandler DGV1.CellValueChanged, AddressOf DGV1_CellValueChanged
     
     '  en sortie de la boucle, on réactive l'événement qui porte sur la modification du DGV1
     
            AddHandler DGV1.CellValueChanged, AddressOf DGV1_CellValueChanged
    Jérémy

  13. #13
    Membre émérite Avatar de Phil Rob
    Homme Profil pro
    Retraité
    Inscrit en
    Novembre 2013
    Messages
    1 613
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Novembre 2013
    Messages : 1 613
    Points : 2 865
    Points
    2 865
    Par défaut
    Bonjour,
    Tu traites un fichier TXT de plus de 800 lignes. A priori, c'est dérisoire. Mais quelles sont les longueurs des lignes ? Moins de 200 à 300 caractères, je pense que c'est toujours dérisoire. Mais comment extrais-tu les infos sur base desquelles tu gères le DGV ?
    Je pense que pour le DGV, 800 lignes est moins dérisoire que pour le fichier. Mais tous les meilleurs conseils pour améliorer les performances du DGV t'ont été donnés. Alors je demande si le problème ne vient pas de ton algorithmique...
    J'espère que ces commentaires te serviront ...

Discussions similaires

  1. Temps de traitement select trop long
    Par David79 dans le forum Requêtes
    Réponses: 1
    Dernier message: 19/05/2013, 11h37
  2. Traitement LDAP trop long!
    Par ludojojo dans le forum C#
    Réponses: 12
    Dernier message: 05/05/2011, 10h29
  3. Traitement XML trop long et plante
    Par corgato dans le forum Qt
    Réponses: 8
    Dernier message: 05/06/2010, 14h59
  4. Temps de Traitement trop long
    Par RGShoop dans le forum VBA Access
    Réponses: 2
    Dernier message: 21/06/2007, 15h41
  5. [Système] Traitement trop long, géré le timeout
    Par Oberown dans le forum Langage
    Réponses: 2
    Dernier message: 01/08/2006, 08h44

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo