Macro qui prend beaucoup de temps...

Christian0258

XLDnaute Accro
Bonjour à tout le forum,

Je souhaiterais votre aide pour cette macro.
Comment la modifier pour quelle fonctionne plus rapidement...?
Est-ce que la zone à traiter (A1:R10000) peut-être remplacée par une zone nommée qui s'adapterait en allant... ???

Merci pour votre aide si précieuse.

Bien amicalement,
Christian


Private Sub Worksheet_Activate()
ActiveSheet.Unprotect ("1912")
Sheets("Saisies").[A1:R10000].AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=[W1:W2], CopyToRange:=[A1:R1]
ActiveSheet.Protect ("1912")
End Sub
 

Jacky67

XLDnaute Barbatruc
Bonjour à tout le forum,

Je souhaiterais votre aide pour cette macro.
Comment la modifier pour quelle fonctionne plus rapidement...?
Est-ce que la zone à traiter (A1:R10000) peut-être remplacée par une zone nommée qui s'adapterait en allant... ???

Merci pour votre aide si précieuse.

Bien amicalement,
Christian


Private Sub Worksheet_Activate()
ActiveSheet.Unprotect ("1912")
Sheets("Saisies").[A1:R10000].AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=[W1:W2], CopyToRange:=[A1:R1]
ActiveSheet.Protect ("1912")
End Sub
Bonjour,
Et en mettant le calcul sur manuel pendant l'exécution ??

*Hello Jean marie
 

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Bonjour à tous
une première chose, quand on travaille sur de grands ensembles de données, est d'éviter d'utiliser la méthode evaluate qui peut ralentir Excel d'autant plus que les données sont importantes
Essayes déja avec ce code sans evaluate

Private Sub Worksheet_Activate()
ActiveSheet.Unprotect ("1912")
Sheets("Saisies").Range("A1:R10000").AdvancedFilter Action:=xlFilterCopy, _
CriteriaRange:=Range("W1:W2"), CopyToRange:=Range("A1:R1")
ActiveSheet.Protect ("1912")
End Sub
 

laetitia90

XLDnaute Barbatruc
bonjour tous :):):)

essai de l'ecrire comme cela
VB:
Private Sub Worksheet_Activate()
   With Application: .ScreenUpdating = 0: .DisplayAlerts = 0: .EnableEvents = 0: .Calculation = 0: End With
   ActiveSheet.Unprotect ("1912")
  Sheets("Saisies").Range("A1:R10000").AdvancedFilter Action:=xlFilterCopy, _
  CriteriaRange:=Range("W1:W2"), CopyToRange:=Range("A1:R1")
  ActiveSheet.Protect ("1912")
   With Application: .ScreenUpdating = 1: .DisplayAlerts = 1: .EnableEvents = 1: .Calculation = 1: End With
End Sub
 

Christian0258

XLDnaute Accro
Re, le forum, jacky67, Yeahou et laetitia90

Merci à vous pour votre aide et solution.
laetitia90 toujours aussi long...
jacky67 ton fichier fonctionne très rapidement, justement je me pose la question, sur le mien dans la feuille Saisies j'ai des formules sur plusieurs colonnes et sur 10000 lignes... et ce que le problème et là ???

Merci à vous.
Bien amicalement,
Christian
 

Jacky67

XLDnaute Barbatruc
jacky67 ton fichier fonctionne très rapidement, justement je me pose la question, sur le mien dans la feuille Saisies j'ai des formules sur plusieurs colonnes et sur 10000 lignes... et ce que le problème et là ???
Re...
Certainement..
Mais sans le classeur impossible de vérifier

*Si tu n'as pas besoin des formules
Tu peux essayer un filtre et copy avec l'instruction "PasteSpecial Paste:=xlPasteValues"
 
Dernière édition:

Dranreb

XLDnaute Barbatruc
Bonjour.
une première chose, quand on travaille sur de grands ensembles de données, est d'éviter d'utiliser la méthode evaluate qui peut ralentir Excel d'autant plus que les données sont importantes
Certainement pas. Parce que Evaluate évalue seulement le texte qui lui est soumis en paramètre, et renvoie ce en quoi Excel l'interprète. Ce n'est donc pas ce que ce texte représente qui est évalué puisque ça ce n'est précisément que le verdict, le seul résultat de cette évaluation. Si par exemple le texte est analysé par Excel comme une adresse de plage de cellules, la méthode renvoie simplement un objet Range qui la représente, mais cette plage n'est pas pour autant à son tour spécialement évaluée. Un ralentissement ne saurait résulter que de l'invocation implicite, dans la foulée, de sa propriété Value, ce qui obligerait Excel à évaluer des formules. Ça peut toutefois être un peu plus compliqué si le texte spécifié est un nom dans le classeur ayant une référence se ramenant à autre chose qu'un objet de l'application, tel qu'un tableau d'éléments Variant.
 
Dernière édition:

Bernard_XLD

XLDnaute Barbatruc
Membre du Staff
Bonjour le forum

Dranreb, je n'avais pas vu ton post plus tôt, je n'aime pas trop polémiquer mais je ne peux laisser sans réponse. Pour illustrer ce que j'ai dit, je prends un cas simple:
1000 lignes et 1000 colonnes, je remplis un tableau visual basic avec une boucle (pas la peine de me préciser qu'il y a plus simple pour remplir un tableau, je le sais, c'est pour la démo)
Deux procédures, une avec Evaluate, une avec une référence précise, un code pour mesurer le temps de traitement.
Aucune formule, aucun nom, une valeur texte dans chaque cellule
Si je suis ton affirmation, il ne devrait y avoir aucune différence de temps de traitement.

Bien cordialement

voici les codes :
Sub Remplissage_Tableau_Evaluate()
Dim Heure_Résultat(1 To 4) As Integer, Heu_Deb As Double, Heu_Fin As Double, Heu_Temp As Double
Dim Compteur As Integer, Compteur2 As Integer
Dim Tab_Test(0 To 999, 0 To 999) As String, Message_Résultat As String

'début timer
Heu_Deb = Timer

'début test
For Compteur = 0 To 999
For Compteur2 = 0 To 999
Tab_Test(Compteur, Compteur2) = [A1].Offset(Compteur2, Compteur).Value
Next Compteur2
Next Compteur

'calcul temps d'exécution
Heu_Fin = Timer - Heu_Deb
If Heu_Fin < 0 Then Heu_Fin = Heu_Fin + 86400 'si passe minuit
Heure_Résultat(1) = Fix(Heu_Fin / 3600)
Heure_Résultat(2) = Fix((Heu_Fin - (Heure_Résultat(1) * 3600)) / 60)
Heure_Résultat(3) = Fix(Heu_Fin - ((Heure_Résultat(1) * 3600) + (Heure_Résultat(2) * 60)))
Heure_Résultat(4) = CInt((Heu_Fin - Fix(Heu_Fin)) * 100)
If Heure_Résultat(1) = 0 Then
If Heure_Résultat(2) = 0 Then
If Heure_Résultat(3) = 0 Then
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
Else
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(3), 2) & " secondes, " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
End If
Else
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(2), 2) & " minutes, " & Right("0" & Heure_Résultat(3), 2) & " secondes, " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
End If
Else
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(1), 2) & " heures, " & Right("0" & Heure_Résultat(2), 2) & " minutes, " & Right("0" & Heure_Résultat(3), 2) & " secondes, " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
End If

MsgBox Message_Résultat

End Sub
Sub Remplissage_Tableau_Référencé()
Dim Heure_Résultat(1 To 4) As Integer, Heu_Deb As Double, Heu_Fin As Double, Heu_Temp As Double
Dim Compteur As Integer, Compteur2 As Integer
Dim Tab_Test(0 To 999, 0 To 999) As String, Message_Résultat As String

'début timer
Heu_Deb = Timer

'début test
For Compteur = 0 To 999
For Compteur2 = 0 To 999
Tab_Test(Compteur, Compteur2) = ActiveSheet.Range("A1").Offset(Compteur2, Compteur).Value
Next Compteur2
Next Compteur

'calcul temps d'exécution
Heu_Fin = Timer - Heu_Deb
If Heu_Fin < 0 Then Heu_Fin = Heu_Fin + 86400 'si passe minuit
Heure_Résultat(1) = Fix(Heu_Fin / 3600)
Heure_Résultat(2) = Fix((Heu_Fin - (Heure_Résultat(1) * 3600)) / 60)
Heure_Résultat(3) = Fix(Heu_Fin - ((Heure_Résultat(1) * 3600) + (Heure_Résultat(2) * 60)))
Heure_Résultat(4) = CInt((Heu_Fin - Fix(Heu_Fin)) * 100)
If Heure_Résultat(1) = 0 Then
If Heure_Résultat(2) = 0 Then
If Heure_Résultat(3) = 0 Then
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
Else
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(3), 2) & " secondes, " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
End If
Else
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(2), 2) & " minutes, " & Right("0" & Heure_Résultat(3), 2) & " secondes, " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
End If
Else
Message_Résultat = "Tableau rempli en " & Right("0" & Heure_Résultat(1), 2) & " heures, " & Right("0" & Heure_Résultat(2), 2) & " minutes, " & Right("0" & Heure_Résultat(3), 2) & " secondes, " & Right("0" & Heure_Résultat(4), 2) & " centièmes"
End If

MsgBox Message_Résultat

End Sub
 

Pièces jointes

  • Démo_Référence _ou_Evaluate.xlsm
    2.5 MB · Affichages: 44

Dranreb

XLDnaute Barbatruc
Bonjour.
La méthode Evaluate peut être légèrement plus longue que la méthode Range parce qu'elle a plus de possibilités et serait susceptible de renvoyer aussi autre chose qu'un objet Range, mais ça n'a toujours rien à voir avec l'hypothèse que si c'est un Range, les cellules qu'il représente feraient l'objet d'une quelconque évaluation, comme vous sembliez le croire. Mais l'un comme l'autre doivent être employés le moins souvent possible. Si possible une seule fois au début et une seule fois à la fin, pour travailler toujours essentiellement avec des tableaux entre les deux. Dans ces condition il n'y a pas de différence perceptible. Bien sûr en l'exécutant 1 million de fois la différence est forcément très amplifiée !
Le fait que le demandeur utilisait des Evaluate en employant des adresses de plages entre crochets droits ne saurait à mon avis expliquer les lenteurs qu'il avait. Et je ne saurais trouver ce qui l'expliquerait vu que c'est un demandeur qui ne joint pas de classeur. Un de ceux auquel je ne répond donc jamais, surtout pour des questions de cet ordre.
 
Dernière édition:

Statistiques des forums

Discussions
312 177
Messages
2 085 972
Membres
103 073
dernier inscrit
MSCHOE16