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 :

Existe-t-il un équivalent de "Loop" pour les boucles "For"


Sujet :

Macros et VBA Excel

  1. #1
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 57
    Points : 45
    Points
    45
    Par défaut Existe-t-il un équivalent de "Loop" pour les boucles "For"
    Bonjour,

    Ma question concerne les cas ou une boucle parcourt un tableau pour chercher une valeur (par exemple), et que dès que la valeur est trouvée il n'y a plus besoin de continuer la boucle (donc autant passer à l'itération suivante pour rapidifier l'opération)...
    @édit: désolée cet exemple induisait en erreur: il ne faut pas sortir de la boucle, mais juste passer au suivant

    Quand c'est le cas avec une boucle While par exemple on fait donc:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Do While blablabla
    (blablabla opérations à répéter)
    if (condition) then Loop
    ("suite des opérations")
    Loop
    Ainsi quand la condition "condition" est réalisée, on itère directement la boucle WHILE sans faire le reste des opérations ("suite des opérations").

    Mais en essayant de faire la même chose dans une boucle For (--> if condition then next), ça a refusé de compilé (Erreur débogage: "Next sans boucle For").

    Savez vous comment procéder pour itérer sans faire la suite des opérations dans une boucle "for" (mais sans sortir de la boucle non plus, donc pas "Exit For").

    Merci d'avance pour toute aide.

  2. #2
    Membre chevronné Avatar de wilfried_42
    Homme Profil pro
    Auto-entrepreneur
    Inscrit en
    Novembre 2006
    Messages
    1 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Auto-entrepreneur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 427
    Points : 1 900
    Points
    1 900
    Par défaut
    Bonjour

    il y a dans le basic une commande assez Barbare que je n'utilise plus depuis des années tellement c'est laid (surtout quand elle son cumulée) à la fin on ne sait même plus ou on va.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    For i = 1 to 200
          Montraitement
          Si la condition est ok : GOTO suite
          Mon2eme traitement
    :suite
    Next i
    mais franchement à ne pas faire. les boucles do loop ont été aussi faites pour éviter les gosub et goto
    Wilfried

  3. #3
    Membre expérimenté
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    673
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 673
    Points : 1 580
    Points
    1 580
    Par défaut
    Bonjour,
    Petite question : pourquoi ne pas vouloir utiliser le Exit For ? Il est en principe fait pour ça...

  4. #4
    Membre chevronné Avatar de wilfried_42
    Homme Profil pro
    Auto-entrepreneur
    Inscrit en
    Novembre 2006
    Messages
    1 427
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 61
    Localisation : France, Vendée (Pays de la Loire)

    Informations professionnelles :
    Activité : Auto-entrepreneur
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 427
    Points : 1 900
    Points
    1 900
    Par défaut
    Boujour

    Citation Envoyé par tedo01 Voir le message
    Bonjour,
    Petite question : pourquoi ne pas vouloir utiliser le Exit For ? Il est en principe fait pour ça...
    telle qu'est posée la question avec son exemple exit for ne convient pas, d'aprés ce que j'ai compris, il ne désire pas sortir de la boucle mais selon une certaine condition ne pas effectuer le traitement à venir et passer à l'enregistrement suivant.

    finalement dormir peut servir lol

    Pourquoi tester une valeur alors qu'on peut tester la non valeur
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    If drapeau = true then  loop
    montraitement
    loop
    fait pareil que :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    If drapeau<>true then
         mon traitement
    end if
    Loop
    Wilfried

  5. #5
    Membre chevronné
    Inscrit en
    Août 2006
    Messages
    1 588
    Détails du profil
    Informations forums :
    Inscription : Août 2006
    Messages : 1 588
    Points : 2 178
    Points
    2 178
    Par défaut
    Bonjour,
    Il est possible d'imbriquer deux boucles
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Do While blablabla
      Do While condition
       (blablabla opérations à répéter)
      Loop   
     ("suite des opérations")
    Loop

  6. #6
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    On peut faire sans pb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    For ...
        traitement commun
        If <condition> Then
            Traitement particulier = "suite de opérations"
        end If
    Next
    Cordialement,

    PGZ
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  7. #7
    Expert éminent
    Homme Profil pro
    Inscrit en
    Août 2010
    Messages
    3 453
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations forums :
    Inscription : Août 2010
    Messages : 3 453
    Points : 6 871
    Points
    6 871
    Par défaut
    Bonjour,

    L'erreur :
    "Erreur débogage: "Next sans boucle For"
    vient probablement du fait que le For se trouve dans un bloc If Then End If et le Next à l'extérieur de ce bloc. onc, le compilateur ne voit pas le For. Soit tu rentre le Next dans le bloc If soit tu sort le For du bloc If.
    Généralement, une boucle Do Loop est utilisée quand on ne connait pas les limites de l'objet que l'on veut parcourir par contre, une boucle For ou For Each est tout à fait indiquée pour parcourir un objet dont on connait les limites :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    For I = 1 To UBound(Tbl)
     
        If Tbl(I) = Condition Then Exit For
     
    Next
    'ici, récup soit de I soit autre traîtement...
    Hervé.

  8. #8
    Membre expérimenté
    Profil pro
    Inscrit en
    Novembre 2006
    Messages
    1 563
    Détails du profil
    Informations personnelles :
    Âge : 61
    Localisation : France

    Informations forums :
    Inscription : Novembre 2006
    Messages : 1 563
    Points : 1 691
    Points
    1 691
    Par défaut
    Citation Envoyé par statista
    plus besoin de continuer la boucle (donc autant passer à l'itération suivante
    c'est une contradiction, passe a l'itération suivante signifie continuer la boucle
    je pense comme theze qu'il te manque tout simplement un end if quelque part
    essaye ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    Sub test()
    For i = 1 To 3
     If i = 2 Then MsgBox "valeur trouvée": Exit For
    Next i
    MsgBox "opération suivante"
    End Sub
    par contre si tu l'écris comme ça
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
     
    Sub test()
    For i = 1 To 3
     If i = 2 Then
     MsgBox "valeur trouvée"
     Exit For
    Next i
    MsgBox "opération suivante"
    End Sub
    tu déclenche next sans for car il te manque le end if
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub test()
    For i = 1 To 3
     If i = 2 Then
     MsgBox "valeur trouvée"
     Exit For
    End If
    Next i
    MsgBox "opération suivante"
    End Sub

  9. #9
    pgz
    pgz est déconnecté
    Expert éminent Avatar de pgz
    Homme Profil pro
    Développeur Office VBA
    Inscrit en
    Août 2005
    Messages
    3 692
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 70
    Localisation : France

    Informations professionnelles :
    Activité : Développeur Office VBA
    Secteur : Conseil

    Informations forums :
    Inscription : Août 2005
    Messages : 3 692
    Points : 6 591
    Points
    6 591
    Par défaut
    Bonjour.

    Il faudrait que statista précise sa question.
    J'ai compris qu'il voulait parcourir une boucle For... Next et pour tous les éléments appliquer un traitement. De plus, pour certains d'entre eux (ceux qui satisfont une condition) faire un traitement supplémentaire.
    Si c'est bien cela, une instruction Exit For ne peut pas convenir, puisque les éléments suivants ne seront pas traités.

    Statista essayait de faire qqc comme
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Sub subForNext2()
    Dim s As String, i As Integer
     
    For i = 1 To 6
        'traitement
        Debug.Print i - 1 & " : " & s
        'traitement sous condition
        If i Mod 2 = 1 Then Next i
        s = s & "A"
    Next i
     
    Debug.Print i - 1 & " : " & s
     
    End Sub
    Cette syntaxe n'est pas acceptée par le compilateur.

    Par contre les solutins de Wilfried me semble répondre au pb. J'en proposait une variante simple
    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
    Sub subForNext()
    Dim s As String, i As Integer
     
    For i = 1 To 6
        'traitement
        Debug.Print i - 1 & " : " & s
        If i Mod 2 = 0 Then 'si i est pair
            'traitement sous condition
            s = s & "A"
        End If
    Next i
     
    Debug.Print i - 1 & " : " & s
     
    End Sub
    Mais je n'ai peut-être rien compris au pb...

    Bon dimanche,

    PGZ

    Edit : correction de confusion de noms. L'auteur de la discussion est statista.
    pluritas non est ponenda sine necessitate - Le rasoir d'Okham
    Ne jamais attribuer à la malignité ce que la stupidité peut expliquer -Le rasoir d'Hanlon

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mai 2008
    Messages
    364
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mai 2008
    Messages : 364
    Points : 350
    Points
    350
    Par défaut
    Bonjour,

    contrairement à statista, j'ai le même problème avec un Do et un For !
    Puisque Goto existe (sous entendu : utiliser avec discernement) je ferais, par exemple :
    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
     
    Sub t()
        [A:B].Clear
        Do While l < 100
            l = l + 1
            Cells(l, 1) = Int(Rnd() * 10 + 1)
            If Cells(l, 1) = 5 Then GoTo 1 ' si Loop  --> Erreur
            Cells(l, 2) = Cells(l, 1)
    1   Loop
    End Sub
    Sub t1()
        [A:B].Clear
        For l = 1 To 100
            Cells(l, 1) = Int(Rnd() * 10 + 1)
            If Cells(l, 1) = 5 Then GoTo 1 ' si Next --> Erreur
            Cells(l, 2) = Cells(l, 1)
    1   Next
    End Sub
    A noter que pour, dans le premier code, on peut être tenté par :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
     
    Sub t()
        [A:B].Clear
        Do While l < 100
            l = l + 1
            Cells(l, 1) = Int(Rnd() * 10 + 1)
            If Cells(l, 1) = 5 Then l=l+1
            Cells(l, 2) = Cells(l, 1)
        Loop
    End Sub
    mais on se retrouve avec une ligne superflue donc on change de problème !

    Là aussi, changer la variable boucle dans la boucle n'est gère recommandé tout du moins à faire avec discernement.

    Tiens, cela me rappelle les grands affrontements "Application.EnableEvents" ,".Select" ...

  11. #11
    Membre expérimenté
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    673
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 673
    Points : 1 580
    Points
    1 580
    Par défaut
    Bonjour,
    Pour moi, on peut toujours coder sans Goto, et c'est la méthode à privilégier.
    Par exemple, je trouve que le code de OrDonc écrit comme suit est beaucoup plus propre et fait la même chose qu'avec les Goto :
    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
    Sub t()
        [A:B].Clear
        Do While l < 100
            l = l + 1
            Cells(l, 1) = Int(Rnd() * 10 + 1)
            If Cells(l, 1) <> 5 Then
                Cells(l, 2) = Cells(l, 1)
            End If
        Loop
    End Sub
    Sub t1()
        [A:B].Clear
        For l = 1 To 100
            Cells(l, 1) = Int(Rnd() * 10 + 1)
            If Cells(l, 1) <> 5 Then
                Cells(l, 2) = Cells(l, 1)
            End If
        Next
    End Sub

  12. #12
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 57
    Points : 45
    Points
    45
    Par défaut
    Bonjour,
    Tout d'abord, merci à tout le monde pour sa participation.

    Pour préciser un peu le pourquoi de la question: je parcours toutes les lignes d'un tableau pour leur affecter un "critère" booléen (vrai ou faux). Par défaut ce critère est vrai, mais il y a plein de raisons qui peuvent faire qu'il soit faux, et une seule raison suffit. Je teste donc ces raisons une par une, mais une fois que le critère est faux ce n'est pas la peine de regarder les autres raisons, car il reste faux.

    Voilà pourquoi je cherche à itérer dès que critère devient faux pour la ligne, sans toutefois sortir de la boucle (le critère doit continuer d'être affecté pour chaque ligne). Au début je pensais à mettre des "if", mais cela aurait fait trop de "if" imbriqués et je finis toujours par m'y perdre quand il y en a trop. J'ai un peu le même souci pour "loop", car il y a déjà beaucoup de boucle while à l’intérieur de la boucle for (il y a plusieurs séries de test, à chaque fois sous la forme de boucle while), j'ai peur que les loop se marchent dessus.

    Par contre je viens de tester avec GoTo (bien que ça ait l’air déconseillé) et ça marche, merci beaucoup, même si je sais que ça n’a pas l’air très approuvé…

    (Si quelqu’un souhaite que je mette le code, je peux, je ne l’ai pas mis car il est un peu long et je ne pense pas que quelqu’un rentrerait dedans).
    Merci.

  13. #13
    Membre expérimenté
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    673
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 673
    Points : 1 580
    Points
    1 580
    Par défaut
    Bonjour,

    Je reviens à la charge (je n'aime vraiment pas les Goto ).
    Pour ce genre de tests en cascade, un seul If avec des Or entre chaque condition peut fonctionner (il ne faut pas avoir une trop grande quantité).
    Sinon, il y a aussi le ElseIf qui évite d'avoir trop de niveaux d'imbrication :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    If condition1 Then
       traitement1
    ElseIf confition2 Then
       traitement2
    ElseIf confition3 Then
       traitement3
    End If

  14. #14
    Membre du Club
    Inscrit en
    Mai 2009
    Messages
    57
    Détails du profil
    Informations forums :
    Inscription : Mai 2009
    Messages : 57
    Points : 45
    Points
    45
    Par défaut
    Mais pourquoi tant de haine contre goto?
    Merci en tout cas pour cette suggestion, je ne connaissais pas "ElseIf", je pense que ça me servira souvent.

  15. #15
    Membre expérimenté
    Femme Profil pro
    Ingénieur développement logiciels
    Inscrit en
    Juin 2007
    Messages
    673
    Détails du profil
    Informations personnelles :
    Sexe : Femme
    Localisation : France, Ain (Rhône Alpes)

    Informations professionnelles :
    Activité : Ingénieur développement logiciels
    Secteur : Conseil

    Informations forums :
    Inscription : Juin 2007
    Messages : 673
    Points : 1 580
    Points
    1 580
    Par défaut
    Re,

    Ma "haine" du Goto n'est pas seulement une réaction de puriste (quoi que...).
    C'est pour moi une instruction qui casse la logique des structures de contrôle du code (If, While, For, ...) et donc risque de rendre la maintenance (en particulier par une autre personne) du code plus compliquée.
    Maintenant, ce n'est qu'un avis...

  16. #16
    Expert éminent sénior
    Profil pro
    Inscrit en
    Décembre 2007
    Messages
    6 803
    Détails du profil
    Informations personnelles :
    Localisation : France, Hérault (Languedoc Roussillon)

    Informations forums :
    Inscription : Décembre 2007
    Messages : 6 803
    Points : 32 061
    Points
    32 061
    Par défaut
    je suis un puriste, j'aime pas les go to, et j'aime pas les elseif non plus.

    parceque ce sont des instructions qui, à mon sens, mettent le doute dans l'esprit du lecteur. ça marche très bien, mais à la maintenance, c'est bof. J'ai tendance à préférer le select case true, avec ci-joint un exemple bidon :

    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
    Dim i As Integer
    Dim j As Integer
    Dim k As Integer
    Dim l As Integer
    Dim m As Integer
    Dim Condition As Boolean
     
    Select Case True
        Case i = 2
            Condition = False
        Case j <> 4
            Condition = False
            i = 8
        Case l > m
            Condition = False
        Case Else
            Condition = True
    End Select
    C'est très proche d'un if - elseif, mais j'ai tendance à trouver ça plus lisible. Mais si ma haine des elseif est discutable(et sera sans doute discutée), celle des go to est largement partagée par les vétérans, qui tous savent à quel point une maintenance peut partir en sucette à cause de go to qui pourtant avaient l'air bien pensés.....
    Les 4 règles d'airain du développement informatique sont, d'après Michael C. Kasten :
    1)on ne peut pas établir un chiffrage tant qu'on a pas finalisé la conception
    2)on ne peut pas finaliser la conception tant qu'on a pas complètement compris toutes les exigences
    3)le temps de comprendre toutes les exigences, le projet est terminé
    4)le temps de terminer le projet, les exigences ont changé
    Et le serment de non-allégiance :
    Je promets de n’exclure aucune idée sur la base de sa source mais de donner toute la considération nécessaire aux idées de toutes les écoles ou lignes de pensées afin de trouver celle qui est la mieux adaptée à une situation donnée.

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

Discussions similaires

  1. [Matériel] L'équivalent d'une adresse MAC pour les puce GPS
    Par Ignescence dans le forum Apple
    Réponses: 4
    Dernier message: 04/04/2011, 11h04
  2. Existe-t-il un équivalent de display:inline-table pour IE 7?
    Par Marc22 dans le forum Mise en page CSS
    Réponses: 0
    Dernier message: 12/05/2010, 15h39
  3. Existe-t-il un équivalent de terminal server pour Windows?
    Par kikica dans le forum Autres Logiciels
    Réponses: 1
    Dernier message: 27/08/2005, 18h09
  4. [T-SQL] existe-t-il un équivalent à EXIT ?
    Par Oluha dans le forum MS SQL Server
    Réponses: 4
    Dernier message: 06/05/2005, 13h52
  5. Réponses: 1
    Dernier message: 17/01/2005, 16h33

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