IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Temps d'exécution d'une boucle sur un range


Sujet :

Macros et VBA Excel

  1. #1
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    juillet 2017
    Messages
    944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : juillet 2017
    Messages : 944
    Points : 355
    Points
    355
    Par défaut Temps d'exécution d'une boucle sur un range
    Bonjour,

    par curiosité j'ai testé 2 boucles de Range pour copier une cellule dans une autre

    Une 1ere boucle en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil1.Range("A" & lig) = Feuil1.Range("B" & lig)
    Une seconde en faisant :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil1.Range("B" & lig).Copy Feuil1.Range("A" & lig)
    La seconde boucle est beaucoup plus rapide, j'ai peut être lu une explication, la 1ere boucle passe par le presse papier pas la seconde ?
    Il ne savait pas que c'était impossible, donc il l' a fait...

  2. #2
    Membre averti Avatar de Alex020181
    Homme Profil pro
    Prestataire informatique développeur d'application Excel, Access, VBA
    Inscrit en
    juin 2012
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Prestataire informatique développeur d'application Excel, Access, VBA

    Informations forums :
    Inscription : juin 2012
    Messages : 203
    Points : 336
    Points
    336
    Par défaut
    Bonjour,

    La seconde est plus rapide ? Pas la première ?

    Pour ma part je pencherait pour la première...

    .copy (la seconde) passe par le presse papier comme vous l'avez vu (=copier/coller). La première duplique directement sans faire l'étape de la copie.
    C'est toujours sympa de savoir si on vous a aidé ou non. Pensez-y

    N'hésitez pas à marquer le sujet comme résolu le cas échéant.

  3. #3
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    mars 2007
    Messages
    2 263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2007
    Messages : 2 263
    Points : 5 125
    Points
    5 125
    Par défaut
    Bonjour,

    Aucune de ces boucles passe par le presse-papier !

    Par contre la première est bien plus rapide, elle ne copie que les valeurs, que la seconde qui copie tout (valeurs, formats, commentaires, validations, ...) :
    Essaies ce test :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    Option Explicit
    Sub test()
    Dim lig As Long
    Dim t0 As Single, t1 As Single, t2 As Single, t3 As Single, t4 As Single
     
      DoEvents
      Application.ScreenUpdating = False
        t0 = Timer
        For lig = 1 To 400
          Feuil1.Range("A" & lig).Value = Feuil1.Range("B" & lig).Value
        Next lig
        t1 = Timer - t0
      DoEvents
        t0 = Timer
        For lig = 1 To 400
          Feuil1.Range("B" & lig).Copy Feuil1.Range("A" & lig)
        Next lig
        t2 = Timer - t0
      DoEvents
      Application.Calculation = xlCalculationManual
        t0 = Timer
        For lig = 1 To 400
          Feuil1.Range("A" & lig).Value = Feuil1.Range("B" & lig).Value
        Next lig
        t3 = Timer - t0
      DoEvents
        t0 = Timer
        For lig = 1 To 400
          Feuil1.Range("B" & lig).Copy Feuil1.Range("A" & lig)
        Next lig
        t4 = Timer - t0
      Application.Calculation = xlCalculationAutomatic
     
      MsgBox "Boucle 1 avec calcul : " & t1 & vbCr & _
             "Boucle 2 avec calcul : " & t2 & vbCr & _
             "Boucle 3 sans calcul : " & t3 & vbCr & _
             "Boucle 4 sans calcul : " & t4
     
    End Sub
    Les DoEvents réduisent les chances que Windows reprenne la main pendant la boucle (volontairement réduite) mais si tu exécutes la boucle plusieurs fois tu verras que ça arrive parfois (le temps de la boucle 1 est alors différent de celui de la 3), l'écart entre la 2 et la 4 dépend des formules dans la feuille.
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  4. #4
    Membre averti Avatar de Alex020181
    Homme Profil pro
    Prestataire informatique développeur d'application Excel, Access, VBA
    Inscrit en
    juin 2012
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Prestataire informatique développeur d'application Excel, Access, VBA

    Informations forums :
    Inscription : juin 2012
    Messages : 203
    Points : 336
    Points
    336
    Par défaut
    Le .copy copie la valeur dans le presse papier.
    J'ai créé un fichier de 50 000 lignes pour test et ouvert un bloc note.

    Pendant que la macro .copy tournait j'ai fait plusieurs ctrlv dans le bloc note et Windows collait la valeur de la cellule Excel. Donc le presse papier est bien utilisé.
    C'est toujours sympa de savoir si on vous a aidé ou non. Pensez-y

    N'hésitez pas à marquer le sujet comme résolu le cas échéant.

  5. #5
    Rédacteur
    Avatar de Philippe Tulliez
    Homme Profil pro
    Formateur, développeur et consultant Excel, Access, Word et VBA
    Inscrit en
    janvier 2010
    Messages
    10 529
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Belgique

    Informations professionnelles :
    Activité : Formateur, développeur et consultant Excel, Access, Word et VBA

    Informations forums :
    Inscription : janvier 2010
    Messages : 10 529
    Points : 24 994
    Points
    24 994
    Billets dans le blog
    29
    Par défaut
    Bonjour Alex,
    Le .copy copie la valeur dans le presse papier.
    Je pense qu'il existe une différence entre la méthode Copy avec ou sans l'argument Destination
    Si l'on fait un Copier/Coller classique, la copie passe par dans le presse papier. En revanche si l'on place le curseur de la souris sur l'un des côtés de la plage à copier ou a déplacer (le pointeur de la souris devient une croix avec flèches) et que l'on déplace, je pense que cela ne passe pas par le presse papier. Il suffit de faire un Ctrl + V pour s'en convaincre
    L'enregistreur de macros génère d'ailleurs un autre code en proposant Copy Destination:=
    Philippe Tulliez
    Ce que l'on conçoit bien s'énonce clairement, et les mots pour le dire arrivent aisément. (Nicolas Boileau)
    Lorsque vous avez la réponse à votre question, n'oubliez pas de cliquer sur et si celle-ci est pertinente pensez à voter
    Mes tutoriels : Utilisation de l'assistant « Insertion de fonction », Les filtres avancés ou élaborés dans Excel
    Ma dernière contribution : VBA - Les macros complémentaires

  6. #6
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    juillet 2017
    Messages
    944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : juillet 2017
    Messages : 944
    Points : 355
    Points
    355
    Par défaut
    #3

    je pensai qu'il fallait ajouter .Value pour ne copier que les valeurs ?
    Il ne savait pas que c'était impossible, donc il l' a fait...

  7. #7
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    mars 2007
    Messages
    2 263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2007
    Messages : 2 263
    Points : 5 125
    Points
    5 125
    Par défaut
    Citation Envoyé par Alex020181 Voir le message
    Le .copy copie la valeur dans le presse papier.
    Effectivement, lors du .copy destination, la copie est aussi envoyée au presse papier, en même temps que dans la plage de destination.
    Mais la copie ne passe pas du presse papier contrairement au cas où on utilise .copy puis .paste :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    Option Explicit
    Sub test()
    Dim lig As Long
    Dim t0 As Single, t1 As Single, t2 As Single, t3 As Single, t4 As Single
     
      DoEvents
      Application.ScreenUpdating = False
        t0 = Timer
        For lig = 1 To 400
          Feuil1.Range("B" & lig).Copy Feuil1.Range("A" & lig)
        Next lig
        t1 = Timer - t0
      DoEvents
        t0 = Timer
        For lig = 1 To 400
          Feuil1.Range("B" & lig).Copy
          Feuil1.Paste Range("A" & lig)
        Next lig
        t2 = Timer - t0
     
      MsgBox "Boucle 1 avec calcul : " & t1 & vbCr & _
             "Boucle 2 avec calcul : " & t2
     
    End Sub
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  8. #8
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    mars 2007
    Messages
    2 263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2007
    Messages : 2 263
    Points : 5 125
    Points
    5 125
    Par défaut
    Citation Envoyé par retraite83 Voir le message
    je pensai qu'il fallait ajouter .Value pour ne copier que les valeurs ?
    Non, quand tu écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil1.Range("A" & lig) = Feuil1.Range("B" & lig)
    C'est pareil, en moins formel, que quand j'écris :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Feuil1.Range("A" & lig).Value = Feuil1.Range("B" & lig).Value
    Car .Value est la propriété par défaut de l'objet Range.
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  9. #9
    Membre averti Avatar de Alex020181
    Homme Profil pro
    Prestataire informatique développeur d'application Excel, Access, VBA
    Inscrit en
    juin 2012
    Messages
    203
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 40
    Localisation : France, Essonne (Île de France)

    Informations professionnelles :
    Activité : Prestataire informatique développeur d'application Excel, Access, VBA

    Informations forums :
    Inscription : juin 2012
    Messages : 203
    Points : 336
    Points
    336
    Par défaut
    En complément le .Value est obligatoire pour attribuer une valeur à plusieurs cellules contiguës.

    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Sheets("Feuil1").Range("A2") = Sheets("Feuil1").Range("A1")

    équivaut à

    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Sheets("Feuil1").Range("A2").Value = Sheets("Feuil1").Range("A1").Value

    Mais si plusieurs cellules contiguës alors il faut le .Value

    Code VBA : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    Sheets("Feuil1").Range("A2:B2").Value = Sheets("Feuil1").Range("A1:B1").Value

    Bon dans ce fil il n'en est pas question mais c'est toujours bon à savoir.
    C'est toujours sympa de savoir si on vous a aidé ou non. Pensez-y

    N'hésitez pas à marquer le sujet comme résolu le cas échéant.

  10. #10
    Expert confirmé Avatar de Patrice740
    Homme Profil pro
    Retraité
    Inscrit en
    mars 2007
    Messages
    2 263
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 67
    Localisation : France, Gironde (Aquitaine)

    Informations professionnelles :
    Activité : Retraité
    Secteur : Aéronautique - Marine - Espace - Armement

    Informations forums :
    Inscription : mars 2007
    Messages : 2 263
    Points : 5 125
    Points
    5 125
    Par défaut
    Citation Envoyé par Alex020181 Voir le message
    Mais si plusieurs cellules contiguës alors il faut le .Value
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Sheets("Feuil1").Range("A2:B2").Value = Sheets("Feuil1").Range("A1:B1").Value
    C'est pour ça qu'il faut prendre les bonnes habitudes de toujours préciser la propriété et le parent (valeur & feuille de calcul).

    A ce propos l'objet Range appartient uniquement à une feuille de calcul, et pas à n'importe quelle feuille, Sheets(xxx).
    La bonne écriture est :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Worksheets("Feuil1").Range("A2:B2").Value = Worksheets("Feuil1").Range("A1:B1").Value
    Cordialement,
    Patrice
    Personne ne peut détenir tout le savoir, c'est pour ça qu'on le partage.

    Pour dire merci, cliquer sur et quand la discussion est finie, penser à cliquer sur

  11. #11
    Membre averti
    Homme Profil pro
    Retraité
    Inscrit en
    juillet 2017
    Messages
    944
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 69
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : juillet 2017
    Messages : 944
    Points : 355
    Points
    355
    Par défaut
    Merci à tous, très intéressant

    j'ai encore appris grâce à vous.
    Il ne savait pas que c'était impossible, donc il l' a fait...

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2007] Suspendre une macro le temps d'exécution d'un script sur SAP
    Par yaciin dans le forum Excel
    Réponses: 2
    Dernier message: 10/03/2014, 11h09
  2. [XSLT] Faire une boucle sur une variable [i]
    Par PoT_de_NuTeLLa dans le forum XSL/XSLT/XPATH
    Réponses: 8
    Dernier message: 07/06/2010, 13h45
  3. Réponses: 1
    Dernier message: 06/05/2008, 14h32
  4. Réponses: 9
    Dernier message: 20/06/2005, 13h17
  5. Affichage du temps d'exécution d'une requête
    Par milka dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 22/03/2004, 18h48

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo