[Déplacé .Net --> VBA] Optimiser une macro

cs_Alban83 Messages postés 24 Date d'inscription vendredi 3 juillet 2009 Statut Membre Dernière intervention 21 septembre 2010 - 13 oct. 2009 à 11:33
cs_Alban83 Messages postés 24 Date d'inscription vendredi 3 juillet 2009 Statut Membre Dernière intervention 21 septembre 2010 - 14 oct. 2009 à 13:31
Bonjour tt le monde,

J'ai créé une macro qui fait une recherche verticale sur deux tableaux de deux feuilles.

Mon problème est que dans les tableaux j'ai énormément de ligne, presque le maximum sur Excel 2003, donc le programme peut mettre plus de deux heures pour finir.

J'aimerai savoir si on peut l'optimiser le programme ? Je pense que c'est les deux boucle For qui ralentie le programme. Comme je ne m'y connais pas en programmation je ne sais pas quoi utiliser.

Merci

Sub rechv()

Worksheets("Default").Activate
Dim ligne1 As Long
ligne1 = Columns("A:A").Find("*", Range("A1"), , , xlByRows, xlPrevious).Row


Dim ligne2 As Long
ligne2 = Columns("A:A").Find("*", Range("A1"), , , xlByRows, xlPrevious).Row

For i = 2 To ligne1

For j = 2 To ligne2

If Cells(i, 1) = Worksheets("Feuil2").Cells(j, 1) Then

Cells(i, 2) = Worksheets("Feuil2").Cells(j, 10)
Exit For

End If
Next j
Next i

End Sub

9 réponses

jmf0 Messages postés 1566 Date d'inscription mardi 26 décembre 2000 Statut Membre Dernière intervention 5 avril 2013 7
13 oct. 2009 à 11:37
Ah !
Une remarque t'a été faite (lorque tu as ouvert cette discussionb sous VB6).
Et voilà que tu ouvres la même sous... VB.Net !!!
Et tu vas bientôt faire un second message du genre "personne pour m'aider" ?
Tu dois (c'est un minimum) savoir sous quoi tu développe et faire l'effort (mille fois plus siomple que celui nécessaire au développement) de rechercher, parmi les thème, celui qui correspond à ton outil de développement.
Désolé, vraiment, une autre fois !
0
jmf0 Messages postés 1566 Date d'inscription mardi 26 décembre 2000 Statut Membre Dernière intervention 5 avril 2013 7
13 oct. 2009 à 14:26
Bon,

Voilà ta question déplacée là où il convient. Regarde où et souviens-t-en pour la prochaine foiis.

On commence par indenter ton code, pour qu'il devienne buvable :

Sub rechv()
  Worksheets("Default").Activate
  Dim ligne1 As Long
  ligne1 = Columns("A:A").Find("*", Range("A1"), , , xlByRows, xlPrevious).Row
  Dim ligne2 As Long
  ligne2 = Columns("A:A").Find("*", Range("A1"), , , xlByRows, xlPrevious).Row
  For i = 2 To ligne1
    For j = 2 To ligne2
      If Cells(i, 1) = Worksheets("Feuil2").Cells(j, 1) Then
        Cells(i, 2) = Worksheets("Feuil2").Cells(j, 10)
        Exit For
      End If
    Next j
  Next i
End Sub


On va maintenant au plus simple et sur la seule base de ton code, sans préjudice de l'examen de ce qu'il est censé faire) :
L'affichage lui-même est en général "gourmand". Si tes lignes sont nombreuses, cela va se faire bien évidemment sentir.
Suggestion, donc : inhiber cet affichage (Application.ScreenUpdating False) avant ta boucle For ... to et le rétablir (Application.ScreenUpdating True) une fois la boucle terminée.

Ceci étant dit : si tes lignes sont nombreuses, tu aurais intérêt à procéder à ces traitement sur un tableau dynamique (obtenu sur la base de ta plage à traiter) plutôt que sur ta feuille directement.
Mais c'est encore autre chose... Commence par ce que je t'ai dit plus haut (injibation de l'affichage pendant le traitement de ta boucle).
0
cs_Alban83 Messages postés 24 Date d'inscription vendredi 3 juillet 2009 Statut Membre Dernière intervention 21 septembre 2010
13 oct. 2009 à 14:58
Merci pour ton aide.

J'ai fait ce que tu m'as dit mais c'est pas mieux.

En cherchant, j'ai trouvé .Fin( ) mais je ne comprend pas à quoi correspond les arguments de Find.
Penses tu que find peut être une solution?
merci
0
us_30 Messages postés 2065 Date d'inscription lundi 11 avril 2005 Statut Membre Dernière intervention 14 mars 2016 10
13 oct. 2009 à 23:52
Bonsoir Alban83 et jmf0,

Je viens de faire une réponse sur l'autre, donc la première présentation... bou...

L'emploi de .Fin( ) est aussi possible, tu gagneras qu'un peu même si cela revient à ne faire plus qu'une seule boucle FOR... car en définitive .Find( ) contient aussi une boucle...

Amicalement,
Us.
0

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

Posez votre question
cs_Alban83 Messages postés 24 Date d'inscription vendredi 3 juillet 2009 Statut Membre Dernière intervention 21 septembre 2010
14 oct. 2009 à 10:03
Merci pour votre aide et dessolé d'avoir merdé dans le choix du thème.

J'ai fait une macro qui me parait bien. Elle se fait en 5 minutes.
Encore merci.


Sub recherchev()

Columns("D:G").Select
Selection.Insert Shift:=xlToRight
Cells(1, 4) = "BP name"
Cells(1, 5) = "Country"
Cells(1, 6) = "Ordering date"
Cells(1, 7) = "Net EURO"

Application.ScreenUpdating = False
tablo = Sheets("Feuil2").Range("A2:J" & Sheets("Feuil2").Range("A65536").End(xlUp).Row)
For n = LBound(tablo, 1) To UBound(tablo, 1)
Set c = Sheets("Default").Columns(1).Find(tablo(n, 1), LookIn:=xlValues, lookat:=xlWhole)
If Not c Is Nothing Then
Sheets("Default").Cells(c.Row, 4) = tablo(n, 4)
Sheets("Default").Cells(c.Row, 5) = tablo(n, 5)
Sheets("Default").Cells(c.Row, 6) = tablo(n, 7)
Sheets("Default").Cells(c.Row, 7) = tablo(n, 10)
End If
Next n
Application.ScreenUpdating = True
End Sub
0
jmf0 Messages postés 1566 Date d'inscription mardi 26 décembre 2000 Statut Membre Dernière intervention 5 avril 2013 7
14 oct. 2009 à 11:26
Salut,

C'était tout le sens de ce que je te disais plus haut

Pour mémoire :

Ceci étant dit : si tes lignes sont nombreuses, tu aurais intérêt à procéder à ces traitement sur un tableau dynamique (obtenu sur la base de ta plage à traiter) plutôt que sur ta feuille directement.
Mais c'est encore autre chose... Commence par ce que je t'ai dit plus haut (injibation de l'affichage pendant le traitement de ta boucle).
0
jmf0 Messages postés 1566 Date d'inscription mardi 26 décembre 2000 Statut Membre Dernière intervention 5 avril 2013 7
14 oct. 2009 à 11:35
Et dis-nous, maintenant.
Puisque tu en as compris le principe et l'a appliqué à la plage de feuille2, pourquoi ne pas l'appliquer également (un autre tableau dynamique) à celle de la feuille Default ?
0
cs_Alban83 Messages postés 24 Date d'inscription vendredi 3 juillet 2009 Statut Membre Dernière intervention 21 septembre 2010
14 oct. 2009 à 11:51
Je me suis un peu emballé.
Il fonctionne quand il y a forcement une correspondance entre le tableau dynamique de la feuille2 avec la feuille Default.
Mais il peut arriver qu’il est des références en plus ou en moins. Et la j’ai l’impression, dans ce cas, que la macro reste bloqué dans la boucle if.

Si je fais un autre tableau dynamique à la feuille default il ira encore plus vite ? Je v voire ça!
0
cs_Alban83 Messages postés 24 Date d'inscription vendredi 3 juillet 2009 Statut Membre Dernière intervention 21 septembre 2010
14 oct. 2009 à 13:31
c'est un autre pb car j'ai fais un test avec 40 lignes il fonctionne bien même si il n'y a pas forcement de correspondance entre les 2 tableaux.
J'ai le pb quand je le fais avec toutes les lignes (environ 40 000) mais si je le force à arrêter au bout de 8 minute je vois que la "recherche vertical" est fini mais la macro reste dans le if d'après de débogage.
0