Enregistrer les modifications faites dans un DataGridView (VB.NET 2005)

Résolu
falstuff Messages postés 40 Date d'inscription jeudi 23 septembre 2004 Statut Membre Dernière intervention 26 avril 2012 - 13 oct. 2009 à 10:28
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 - 13 oct. 2009 à 14:43
Bonjour,
J'ai un probleme de lenteur pour enregistrer les lignes de mon datagridview. Mes DataGridView sont destinées à avoir 200 000 lignes voir plus. J'ai remarqué un gros probleme de lenteur pour une table listant les communes (plus de 32 000 enregistrement). L'utilisateur pouvant saisir directement dans le DataGridView, j'ai rien trouvé d'autre que de parcourir chaque ligne et de faire un uptade ou insert dans ma table. L'action d'enregistrer s'effectue sur la fermeture de la fenetre ou sur clic du bouton enregistrer. Je ne veux pas enregistrer automatiquement à la sortie d'une ligne ou d'une cellule.
Voici le code que j'utilise pour l'affichage des lignes et celui pour enregistrer.
La construction est un particuliere car j'ai pas mal personnalisé ce controle. Le meme datagridview permet d'afficher x source de table. J'ai la premiere ligne qui est une ligne blanche ou l'utilisateur peut effectuer des recherches, ect......
Pour info :
- la variable oCommune est une classe "Metier" pour l'acces à la table commune (Select / Delete / Uptage / Insert....)
- La variable oParametreColonne est également une classe "Metier" sur le meme principe que oCommune. La table ParametreColonne permet de connaitre les colonnes à afficher ou non : les utilisateurs peuvent mémoriser l'affichage et le masquage des colonnes, les dimensions de chaque colonne, la position des colonnes. Ils se créer leur environnement de travail.


L'AFFICHAGE DU DATAGRIDVIEW
Private Sub AfficherDGW_Commune()

Dim bind As BindingSource = New BindingSource
Dim oCommune As Commune = New Commune
Dim i As Integer = 0
DGWDetail.AutoGenerateColumns = False
bind.DataSource = oCommune.LoadAll(pStrWhere)
DGWDetail.DataSource = bind
If pVerifColonneCreer = False Then
Dim dt As DataTable = New DataTable
dt = oParametreColonne.LoadAll(pOrigine)
While i < dt.Rows.Count
'---------------------------------------------------------------
'GESTION DES CASES A COCHEES
'---------------------------------------------------------------
If dt.Rows(i)("TypeColonne") = "Case a cocher" Then
If dt.Rows(i)("NomChamps") = "Actif" Then
Dim CaseActif As DataGridViewCheckBoxColumn = New DataGridViewCheckBoxColumn
'CaseActif.DefaultCellStyle.NullValue = True
CaseActif.CellTemplate.Value = True
DGWDetail.Columns.Add(New DataGridViewCheckBoxColumn)
Else
DGWDetail.Columns.Add(New DataGridViewCheckBoxColumn)
End If
'DGWDetail.Columns.Add(New DataGridViewCheckBoxColumn)
Dim C As DataGridViewCheckBoxColumn = New DataGridViewCheckBoxColumn
C.ThreeState = True
DGWEntete.Columns.Add(C)
Else
If dt.Rows(i)("TypeColonne") = "Liste Deroulante" Then
If dt.Rows(i)("NomChamps") = "Pays" Then
Dim CbPaysEntete As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
DGWEntete.Columns.Add(CbPaysEntete)

Dim CbPaysDetail As DataGridViewComboBoxColumn = New DataGridViewComboBoxColumn
CbPaysDetail.DataSource = oPays.LoadAll()
CbPaysDetail.ValueMember = "Pays"
CbPaysDetail.DisplayMember = "Pays"
CbPaysDetail.DefaultCellStyle.NullValue = "France"
CbPaysDetail.DataPropertyName = "Pays" 'dt.Rows(i)("NomChamps")
CbPaysDetail.DropDownWidth = 500
DGWDetail.Columns.Add(CbPaysDetail)
End If
Else
'---------------------------------------------------------------
'GESTION DES ZONES DE TEXTES
'---------------------------------------------------------------

If dt.Rows(i)("NomChamps") = "IdCommune" Then
Dim TxtIdCommuneEntete As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
'TxtAbreviationEntete.MaxInputLength = 3
DGWEntete.Columns.Add(TxtIdCommuneEntete)

Dim TxtIdCommuneDetail As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
TxtIdCommuneDetail.ReadOnly = True
DGWDetail.Columns.Add(TxtIdCommuneDetail)
End If
If dt.Rows(i)("NomChamps") = "Libelle" Then
Dim TxtLibelleEntete As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
TxtLibelleEntete.MaxInputLength = 50
DGWEntete.Columns.Add(TxtLibelleEntete)

Dim TxtLibelleDetail As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
TxtLibelleDetail.MaxInputLength = 50
DGWDetail.Columns.Add(TxtLibelleDetail)
End If
If dt.Rows(i)("NomChamps") = "CodePostal" Then
Dim TxtCodePostalEntete As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
TxtCodePostalEntete.MaxInputLength = 50
DGWEntete.Columns.Add(TxtCodePostalEntete)

Dim TxtCodePostalDetail As DataGridViewTextBoxColumn = New DataGridViewTextBoxColumn
TxtCodePostalDetail.MaxInputLength = 50
DGWDetail.Columns.Add(TxtCodePostalDetail)
End If
End If
End If
If dt.Rows(i)("TypeColonne") <> "Liste Deroulante" Then
DGWDetail.Columns(i).DataPropertyName = dt.Rows(i)("NomChamps")
End If
DGWDetail.Columns(i).DataPropertyName = dt.Rows(i)("NomChamps")
DGWDetail.Columns(i).Name = dt.Rows(i)("NomChamps")
DGWDetail.Columns(i).HeaderText = dt.Rows(i)("Nomcolonne")
DGWDetail.Columns(i).Width = dt.Rows(i)("Largeur")
DGWEntete.Columns(i).Name = "Rech" & dt.Rows(i)("NomChamps")
DGWEntete.Columns(i).HeaderText = dt.Rows(i)("Nomcolonne")
DGWEntete.Columns(i).Width = dt.Rows(i)("Largeur")
i = i + 1
End While
DGWEntete.Rows.Add()
pVerifColonneCreer = True
End If
DGWDetail.Refresh()
AfficherColonneDGW()
ActiverBouton()
pVerifModif = False
End Sub

L'ENREGISTREMENT DU DATAGRIDVIEW
Public Sub Enregistrer
DGWDetail.EndEdit()

Dim i As Long
While i < DGWDetail.Rows.Count - 1
If pOrigine = "Commune" Then
If Not IsDBNull(DGWDetail.Item("IdCommune", DGWDetail.Rows(i).Index).Value) Then
oCommune.IdCommune = DGWDetail.Item("IdCommune", DGWDetail.Rows(i).Index).Value
oCommune.LoadOne()
oCommune.Libelle = DGWDetail.Item("Libelle", DGWDetail.Rows(i).Index).Value.ToString
oCommune.Pays = DGWDetail.Item("Pays", DGWDetail.Rows(i).Index).Value.ToString
oCommune.CodePostal = DGWDetail.Item("CodePostal", DGWDetail.Rows(i).Index).Value
oCommune.Update()
Else
oCommune.Libelle = DGWDetail.Item("Libelle", DGWDetail.Rows(i).Index).Value.ToString
oCommune.CodePostal = DGWDetail.Item("CodePostal", DGWDetail.Rows(i).Index).Value
oCommune.Pays = DGWDetail.Item("Pays", DGWDetail.Rows(i).Index).Value.ToString
oCommune.Insert()
End If
End If
i = i + 1
End While
End Sub


L'IDEAL SERAIT DE POUVOIR RETENIR UNIQUEMENT LES LIGNES QUI ONT ETES MODIFIER ET AJOUTER. L'UTILISATEUR NE SERA JAMAIS AMENER A MODIFIER OU AJOUTER BEAUCOUP DE LIGNE A LA FOIS.
JE SUIS PRENEUR DE TOUTES SOLUTIONS MEME SI JE DOIS MODIFIER LA GENERATION DE MON DATAGRIDVIEW OU AUTRE

PS : C'EST ASSEZ URGENT

MERCI DE VOS REPONSES ET DE VOTRE AIDE

5 réponses

Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 10
13 oct. 2009 à 14:43
C'est effectivement une solution, mais je persiste à penser, en l'état actuel de la connaissance que j'ai de ton problème qu'un recordset aurait été la meilleure solution couplé avec la modification intégrée dans le DataGridView.


Calade
3
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 10
13 oct. 2009 à 11:37
Bonjour,

Je ne connais .NET ni par conséquent ses DataGridView , mais j'imagine qu'ils fonctionnent peu ou prou comme ceux de VB6.

Dans ton code tu le peuples ligne par ligne en parcourant ta base. De plus tu créé à chaque fois un DataGridViewTextBoxColumn (c'est du .NET ou d'un OCX de ta fabrication ?).

De toutes façons, essayes déjà en utilisant un recordset et lies ensuite ton DataGridView à ce recordset pour l'affichage. Il te suffira ensuite d'exécuter un .Update sur ce recordset pour mettre à jour la table.


Calade
0
falstuff Messages postés 40 Date d'inscription jeudi 23 septembre 2004 Statut Membre Dernière intervention 26 avril 2012 2
13 oct. 2009 à 11:48
Merci de ta réponse Calade,

DataGridViewTextBoxColumn est un objet de .NET

J'utilise un binding pour "peuplé" mon datagridview. c'est un peu comme un recordset (datatable comme source).
Je boucle pour créer mes colonnes sur la table ParametreGenerale, les données de la table Commune sont déjà afficher avant la boucle.
Pour faire un Update directement sur le binding je ne connais pas le principe et si c'est possible (aprés recherche sur le net). De plus, je perd le binding une fois le datagridview construit.
Je ne suis pas un expert en .NET, des choses m'échappe certainement....
0
Calade Messages postés 1207 Date d'inscription dimanche 20 avril 2003 Statut Membre Dernière intervention 4 juin 2016 10
13 oct. 2009 à 14:05
A mon avis il y a beaucoup plus efficient que de parcourir les enregistrements de ta table un par un.

De plus DataGridViewTextBoxColumn permet j'imagine la mise à jour des données, mais ce qui m'étonne c'est que la mise à jour était prévu dans le DataGrid lui-même en VB6 et on le gérait comme on voulait avec des évènements du style Before/AfterUpdate. Regarde de ce côté là aussi.

Enfin regarde l'utilisation d'un Recordset. Avec le 2ème point de ce message, je suis sur que tu pourrais grandement accélérer ton traitement.


Calade
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
falstuff Messages postés 40 Date d'inscription jeudi 23 septembre 2004 Statut Membre Dernière intervention 26 avril 2012 2
13 oct. 2009 à 14:22
Merci beaucoup pour ton aide Calade,

J'ai trouvé une solution qui divise quasiment à 100% le temps d'attente .
La solution que j'ai fait, j'ai déclaré un tableau dynamique qui stocke les clés primaires des enregistrements qui ont été modifié au fur et à mesure des manip de l'utilisateur.
Pour la sauvegarde, j'ai plus qu'a selectionné les bonnes lignes dans le datagridview et d'effectuer la MAJ de la table.

@++
0
Rejoignez-nous