Optimisation de code
Bonjour à tous,
J'ai réalisé un code pour un suivi particulier des récidives dans mon travail. Le problème de mon code c'est qu'à un nombre de lignes importantes le fichier peine.
Pouvez-vous m'éclairer pour l'optimisation de celui-ci ?
Merci à vous !
Option Explicit
Sub DoublonsRapideTous()
Dim d_matériels As Object, d_mat_dates As Object
Dim date_incident As Range, matériel As Range, famille As Range, organe As Range
Dim date_incident_prec As Variant, famille_prec As String, organe_prec As String
Application.Calculation = xlCalculationManual
Application.ScreenUpdating = False
Application.EnableEvents = False
' **Repérage de tous les doublons (entre 2 colonnes + doublons dans chaque colonne)
' -- création d'un dictionnaire des matériels --
' -- et pour chaque matériel d'un dictionnaire des dates d'incident contenant la fammille et l'organe --
Set d_matériels = CreateObject("Scripting.Dictionary")
For Each matériel In [Matériels].Cells
Set date_incident = matériel.Offset(, [Dates_incident].Column - [Matériels].Column)
Set famille = matériel.Offset(, [Familles].Column - [Matériels].Column)
Set organe = matériel.Offset(, [Organes].Column - [Matériels].Column)
famille.Interior.ColorIndex = xlNone: organe.Interior.ColorIndex = xlNone
If Not d_matériels.exists(matériel.Value) Then
Set d_matériels(matériel.Value) = CreateObject("Scripting.Dictionary")
Set d_mat_dates = d_matériels(matériel.Value)
Else
Set d_mat_dates = d_matériels(matériel.Value)
For Each date_incident_prec In d_mat_dates.keys
famille_prec = d_mat_dates(date_incident_prec)(0)
organe_prec = d_mat_dates(date_incident_prec)(1)
If date_incident - date_incident_prec <= 30 Then
If famille = famille_prec Then famille.Interior.ColorIndex = 4
If famille = "" Then famille.Interior.ColorIndex = 0
If organe = organe_prec Then organe.Interior.ColorIndex = 3
If organe = "" Then organe.Interior.ColorIndex = 0
End If
Next date_incident_prec
End If
' mise à jour du dictionnaire des dates d'incident pour le matériel du dictionnaire des matériels
d_mat_dates(date_incident.Value) = Array(famille.Value, organe.Value)
Set d_matériels(matériel.Value) = d_mat_dates
Next matériel
Application.Calculation = xlCalculationAutomatic
Application.ScreenUpdating = True
Application.EnableEvents = True
End SubBonjour,
Le principal problème que je vois c'est que le code ne fait qu'utiliser des Range pendant toute son exécution, pour le parcours des lignes de ton tableau, il serait beaucoup plus rapide d'utiliser une variable de tableau qui stockerait tes données, je n'ai pas non plus l'impression que tous les dictionnaires servent, surtout celui des dates, enfin il sert dans ton code mais on pourrait s'en passer selon moi. Je ne suis pas sûr du point suivant, mais je crois que remplir les cellules ligne par ligne n'est pas optimal non plus, j'aurais plutôt stocké les adresses petit à petit dans une variable pour ensuite appliquer les mises en forme d'un coup pour toutes les cellules concernées.
Je pourrais tenter la modification du code directement mais sans fichier pour tester et déboguer le code, il y a de grandes chances que ça ne fonctionne pas, pourrais-tu nous transmettre ton fichier? si il contient des données confidentielles tu peux les enlever/modifier pour qu'elles ne le soient plus.
- Messages
- 4'199
- Excel
- 2021 FR 64 bits
- Inscrit
- 13/06/2016
- Emploi
- bénévole associations Goutte d'Or
Bonjour,
Je pense qu'il faut vérifier votre référence de nom "Matériels". Elle est peut être mal bornée et contient donc un nombre excessif de lignes vides.
L'instruction MsgBox Range("Matériels").Rows.Count vous donnera son nombre de lignes qui n'est pas forcément celui des lignes renseignées.
Par ailleurs, d'après votre code, la référence de nom "Matériels" devrait correspondre à une colonne.
L'instruction MsgBox Range("Matériels").Columns.Count doit vous donner 1.
Bonjour,
Je fais un début de travail en améliorant le code, je propose le résultat en pièce jointe pour le moment.
Je dis pour le moment car pour commencer j'ai juste cherché à améliorer le code en gardant à peu près sa logique, sauf que la logique n'est pas très bonne de base j'ai l'impression, le code serait super si il s'agissait juste de cliquer une fois de temps en temps sur un bouton pour tout parcourir, sauf qu'ici il est lancé à chaque modification apporté sur la feuille. Ce qui veut dire qu'on doit juste mettre à jour la ligne mise à jour et celles qui sont liées à celle-ci, et donc limiter le champ d'action du code en filtrant d'abord le matériel pour garder uniquement celui qui nous intéresse, cette modification sera la seconde à apporter dans le fichier, je me demande quand même si ça n'aurait pas été possible de faire ça plus simplement juste avec des mfc sur le tableau...
Bonjour à vous,
Merci du retour que vous avez apporté à mon sujet, Ausecour, je regarde tes lignes de code ce soir pour comprendre mes erreurs.
Je prends tes remarques en considération pour voir si je peux les intégrer.
Merci encore