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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre éprouvé
    Homme Profil pro
    Retraité
    Inscrit en
    Juillet 2017
    Messages
    1 291
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 74
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2017
    Messages : 1 291
    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 ?

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

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

    Informations forums :
    Inscription : Juin 2012
    Messages : 601
    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.

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

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

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    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.

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

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

    Informations forums :
    Inscription : Juin 2012
    Messages : 601
    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é.

  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
    13 176
    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 : 13 176
    Billets dans le blog
    53
    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
    Mon dernier billet : Utilisation de la fonction Dir en VBA pour vérifier l'existence d'un fichier

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

    Informations professionnelles :
    Activité : Retraité

    Informations forums :
    Inscription : Juillet 2017
    Messages : 1 291
    Par défaut
    #3

    je pensai qu'il fallait ajouter .Value pour ne copier que les valeurs ?

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

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

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    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.

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

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

    Informations forums :
    Inscription : Mars 2007
    Messages : 2 478
    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

+ 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, 10h09
  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, 12h45
  3. Réponses: 1
    Dernier message: 06/05/2008, 13h32
  4. Réponses: 9
    Dernier message: 20/06/2005, 12h17
  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, 17h48

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