Thibault LB
XLDnaute Junior
Bonjour à tous,
Je vous explique ma problématique.
Chaque mois un fichier excel est extrait d'une base de données. J'ai besoin de faire une comparaison entre le fichier d'un mois, avec celui du mois précédent. Pour cela, je veux que les cellules qui ont changées soit coloriées en jaune, et si une ligne a été insérée, que toute la ligne soit en jaune, tout ça dans le nouveau fichier.
Ma macro marche très bien. Sauf que les fichiers excel en question font plus de 3700 lignes (pour 37 colonnes), et mon traitement n'arrive jamais au bout (j'ai deja laissé mouliner 1h). J'ai donc fait mes tests finaux sur un fichier redressé a 50 lignes. La fonctionnalité est la, tout marche très bien, avec une résolution immédiate et parfaite, mais le temps de traitement ne me permet pas de l'étendre aux vrais fichiers.
Je me suis dis que peut-être auriez-vous des méthodes pour optimiser un code VBA ?
Voici le code, avec mes explications ci-après :
Pour faire court :
1) Je concatène les 37 colonnes de chaque ligne
2) Je fais mes boucles sur chaque ligne, pour vérifier si les champs concaténés sont présents dans l'ancien fichier. Si une cellule a changé dans la ligne, elle apparaitra différent (ATTENTION : les lignes peuvent ne pas être au même endroit d'un mois sur l'autre, il peut y avoir des insertions ou des suppressions, donc je dois bien regarder toutes les lignes pour chaque ligne (sauf s'il elle est trouvé, pas de doublons possible).).
3) Une fois que j'ai récupérer les lignes contenant une difference, je regarde pour chaque cellule, si elle est identique (les colonnes ne bouge pas en revanche, toujours dans le même ordre).
Si vous avez des questions, n'hesitez pas.
Thibault.
Je vous explique ma problématique.
Chaque mois un fichier excel est extrait d'une base de données. J'ai besoin de faire une comparaison entre le fichier d'un mois, avec celui du mois précédent. Pour cela, je veux que les cellules qui ont changées soit coloriées en jaune, et si une ligne a été insérée, que toute la ligne soit en jaune, tout ça dans le nouveau fichier.
Ma macro marche très bien. Sauf que les fichiers excel en question font plus de 3700 lignes (pour 37 colonnes), et mon traitement n'arrive jamais au bout (j'ai deja laissé mouliner 1h). J'ai donc fait mes tests finaux sur un fichier redressé a 50 lignes. La fonctionnalité est la, tout marche très bien, avec une résolution immédiate et parfaite, mais le temps de traitement ne me permet pas de l'étendre aux vrais fichiers.
Je me suis dis que peut-être auriez-vous des méthodes pour optimiser un code VBA ?
Voici le code, avec mes explications ci-après :
Code:
'Macro permettant de mettre à jour les données France pour chaque onglet, onglet par onglet.
Sub Difference()
'Raccourci clavier : Ctrl + e
'
'Par Thibault Le Bouter
Application.ScreenUpdating = False
'Récupération du fichier actif (depuis lequel on lance la macro) et enregistrement dans l'objet Nouveau.
Dim Nouveau As Workbook
Dim nom As String
nom = ActiveWorkbook.Name
Set Nouveau = Workbooks("" & nom)
'Récupération du fichier avec lequel on veut comparer, par une invite utilisateur. Le fichier est stocké dans l'objet Ancien.
Dim Ancien As Workbook
Dim AN As Variant
AN = Application.GetOpenFilename(FileFilter:="Fichiers Excel (*.xl*), *.xl*", Title:="Choix du fichier de comparaison")
If AN <> False Then
Set Ancien = Workbooks.Open(AN)
End If
Dim i As Long
Dim Valeur As String
Dim Valeur2 As String
Valeur = ""
Valeur2 = ""
Ancien.Worksheets("global").Activate
Last2 = Cells(65536, 2).End(xlUp).Row 'Récupération de la dernière ligne non vide de l'ancien fichier et stockage dans le variable Last2
For J = 5 To Last2
'Concaténation de toutes les colonnes, lignes par lignes.
Cells(J, 38).Value = Cells(J, 2).Value & Cells(J, 3).Value & Cells(J, 4).Value & Cells(J, 5).Value & Cells(J, 6).Value & Cells(J, 7).Value & Cells(J, 8).Value & Cells(J, 9).Value & Cells(J, 10).Value & Cells(J, 11).Value & Cells(J, 12).Value & Cells(J, 13).Value & Cells(J, 14).Value & Cells(J, 15).Value & Cells(J, 16).Value & Cells(J, 17).Value & Cells(J, 18).Value & Cells(J, 19).Value & Cells(J, 20).Value & Cells(J, 21).Value & Cells(J, 22).Value & Cells(J, 23).Value & Cells(J, 24).Value & Cells(J, 25).Value & Cells(J, 26).Value & Cells(J, 27).Value & Cells(J, 28).Value & Cells(J, 29).Value & Cells(J, 30).Value & Cells(J, 31).Value & Cells(J, 32).Value & Cells(J, 33).Value & Cells(J, 34).Value & Cells(J, 35).Value & Cells(J, 36).Value & Cells(J, 37).Value
Next J
Columns("AL").AutoFit
Nouveau.Worksheets("global").Activate
Last = Cells(65536, 2).End(xlUp).Row 'Récupération de la dernière ligne non vide du nouveau fichier et stockage dans le variable Last
For J = 5 To Last
'Concaténation de toutes les colonnes, lignes par lignes.
Cells(J, 38).Value = Cells(J, 2).Value & Cells(J, 3).Value & Cells(J, 4).Value & Cells(J, 5).Value & Cells(J, 6).Value & Cells(J, 7).Value & Cells(J, 8).Value & Cells(J, 9).Value & Cells(J, 10).Value & Cells(J, 11).Value & Cells(J, 12).Value & Cells(J, 13).Value & Cells(J, 14).Value & Cells(J, 15).Value & Cells(J, 16).Value & Cells(J, 17).Value & Cells(J, 18).Value & Cells(J, 19).Value & Cells(J, 20).Value & Cells(J, 21).Value & Cells(J, 22).Value & Cells(J, 23).Value & Cells(J, 24).Value & Cells(J, 25).Value & Cells(J, 26).Value & Cells(J, 27).Value & Cells(J, 28).Value & Cells(J, 29).Value & Cells(J, 30).Value & Cells(J, 31).Value & Cells(J, 32).Value & Cells(J, 33).Value & Cells(J, 34).Value & Cells(J, 35).Value & Cells(J, 36).Value & Cells(J, 37).Value
Next J
Columns("AL").AutoFit
If Last > Last2 Then 'Determination de la taille necessaire du tableau
Dernier = Last
Else
Dernier = Last2
End If
'Intialisation d'un tableau de la taille du nombres maximum de lignes (Possibilité de 5000 lignes max)
Dim NomTableau(5000) As Integer
For K = 0 To Dernier
NomTableau(K) = 0
Next K
'Suppression de possible coloriage de cellule précédemment fait (utile par exemple lors d'une erreur de fichier à comparer, ou s'il on veut comparer avec un autre fichier.
For i = 5 To Last
Nouveau.Worksheets("global").Activate
Range("" & i & ":" & i).Interior.ColorIndex = xlAutomatic
Next i
Nouveau.Worksheets("global").Activate
For i = 5 To Last
Valeur_Test = Nouveau.Worksheets("global").Cells(i, 38).Value 'La valeur qu'on souhaite tester (test sur la valeur précédemment concaténée)
For numLigne = 5 To Last2 'Boucle for déroulant les cellules concaténées de l'autre fichier.
'On verifie si la valeur Valeur_Test du nouveau fichier est contenue dans l'ancien
If Ancien.Worksheets("global").Cells(numLigne, 38).Value = Valeur_Test Then
NomTableau(i) = 0 'Si la valeur est trouvée, on met la ligne du tableau a 0...
Exit For '...et on arrête la boucle.
Else
v = Nouveau.Worksheets("global").Cells(i, 4).Value 'Test sur une colonne a champ unique, pour voir si la ligne existe quand même.
For numLigne2 = 5 To Last2
If Ancien.Worksheets("global").Cells(numLigne2, 4).Value = v Then
NomTableau(i) = numLigne2 'Si trouvé, on insère le numéro de ligne dans le tableau.
Exit For
Else
NomTableau(i) = -1 'Si le code article n'a pas été trouvé, on associe la case a -1 pour traitement plus tard.
'Nouveau.Worksheets("global").Range("" & i & ":" & i).Select 'On selectionne les lignes n'étant pas du tout présente dans l'ancien fichier...
'Selection.Interior.ColorIndex = 6 '...et on leur associe la couleur jaune.
End If
Next numLigne2
End If
Next numLigne
Next i
For J = 5 To Dernier 'On déroule le tableau pour récupérer tous les numéros de lignes enregistrés
If NomTableau(J) <> -1 Then
If NomTableau(J) <> 0 Then 'Si le tableau n'est pas égal à 0 à la case j...
For c = 2 To 37 '... on parcourt toutes les colonnes pour repérer en quelle(s) cellule(s) il y a différence.
Valeur = Nouveau.Worksheets("global").Cells(J, c).Value
'For Each cel In Range("" & NomTableau(J) & ":" & NomTableau(J))
Valeur2 = Ancien.Worksheets("global").Cells(NomTableau(J), c).Value
If Valeur <> Valeur2 Then 'Si
Nouveau.Worksheets("global").Cells(J, c).Interior.ColorIndex = 6 '...on associe la couleur jaune a la cellule
End If
Valeur = "" 'On reinitialise les variables
Valeur2 = ""
Next c
End If
Else 'Si case -1, c'est que la ligne est nouvelle, donc a mettre entierement en jaune.
Nouveau.Worksheets("global").Range("" & J & ":" & J).Select 'On selectionne les lignes n'étant pas du tout présente dans l'ancien fichier...
Selection.Interior.ColorIndex = 6 '...et on leur associe la couleur jaune.
End If
Next J
''Même procédure pour le second onglet.
'Ancien.Worksheets("Par code vrac").Activate
'Last3 = Cells(65536, 2).End(xlUp).Row
'For J = 5 To Last2
' Cells(J, 39).Value = Cells(J, 8).Value & Cells(J, 9).Value & Cells(J, 10).Value & Cells(J, 11).Value & Cells(J, 12).Value & Cells(J, 13).Value & Cells(J, 14).Value & Cells(J, 15).Value & Cells(J, 16).Value & Cells(J, 17).Value & Cells(J, 18).Value & Cells(J, 19).Value & Cells(J, 20).Value & Cells(J, 21).Value & Cells(J, 22).Value & Cells(J, 23).Value & Cells(J, 24).Value & Cells(J, 25).Value & Cells(J, 26).Value & Cells(J, 27).Value & Cells(J, 28).Value & Cells(J, 29).Value & Cells(J, 30).Value & Cells(J, 31).Value & Cells(J, 32).Value & Cells(J, 33).Value & Cells(J, 34).Value & Cells(J, 35).Value & Cells(J, 36).Value & Cells(J, 37).Value & Cells(J, 38).Value
'Next J
'Columns("AM").AutoFit
'
'Nouveau.Worksheets("Par code vrac").Activate
'Last4 = Cells(65536, 2).End(xlUp).Row
'For J = 5 To Last
' Cells(J, 39).Value = Cells(J, 8).Value & Cells(J, 9).Value & Cells(J, 10).Value & Cells(J, 11).Value & Cells(J, 12).Value & Cells(J, 13).Value & Cells(J, 14).Value & Cells(J, 15).Value & Cells(J, 16).Value & Cells(J, 17).Value & Cells(J, 18).Value & Cells(J, 19).Value & Cells(J, 20).Value & Cells(J, 21).Value & Cells(J, 22).Value & Cells(J, 23).Value & Cells(J, 24).Value & Cells(J, 25).Value & Cells(J, 26).Value & Cells(J, 27).Value & Cells(J, 28).Value & Cells(J, 29).Value & Cells(J, 30).Value & Cells(J, 31).Value & Cells(J, 32).Value & Cells(J, 33).Value & Cells(J, 34).Value & Cells(J, 35).Value & Cells(J, 36).Value & Cells(J, 37).Value & Cells(J, 38).Value
'Next J
'Columns("AM").AutoFit
End Sub
Pour faire court :
1) Je concatène les 37 colonnes de chaque ligne
2) Je fais mes boucles sur chaque ligne, pour vérifier si les champs concaténés sont présents dans l'ancien fichier. Si une cellule a changé dans la ligne, elle apparaitra différent (ATTENTION : les lignes peuvent ne pas être au même endroit d'un mois sur l'autre, il peut y avoir des insertions ou des suppressions, donc je dois bien regarder toutes les lignes pour chaque ligne (sauf s'il elle est trouvé, pas de doublons possible).).
3) Une fois que j'ai récupérer les lignes contenant une difference, je regarde pour chaque cellule, si elle est identique (les colonnes ne bouge pas en revanche, toujours dans le même ordre).
Si vous avez des questions, n'hesitez pas.
Thibault.
Dernière édition: