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 :

superposition de conditions [XL-2003]


Sujet :

Macros et VBA Excel

  1. #1
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut superposition de conditions
    Bonjour le forum,

    J'ai créé une macro afin d'extraire les ligne qui comporte la dernière date du mois vers un nouvel onglet (les données sont classées par ordre croissant).
    J'utilise comme condition le fait que si d'une ligne à l'autre le numéro du mois est supérieur cela signifie qu'il faut sélectionner et copier/coller la ligne précédente dans le nouvel onglet.

    Voici la macro:

    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
    Sub MarquerLigne()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim i As Long
        DerLig = 2
        Sheets("Sheet2").Cells.ClearContents
        With Sheets("Sheet1")
            .Cells.Interior.ColorIndex = xlNone
            M = Month(.Cells(2, 2))
            For Lig = 2 To .Range("B65536").End(xlUp).Row
                MC = Month(.Cells(Lig, 2))
                If MC > M Or (MC = 1 And M = 12) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    M = MC
                End If
            Next Lig
        End With
    End Sub
    Ca coince lorsqu'il y a un saut de mois par exemple de novembre (mois 11) à janvier (mois 1) car dans ce cas la macro va ignorer tous les mois jusqu'à atteindre décembre.
    Pour remédier à ce problème je pense que la solution serait d'insérer une condition supplémentaire avec les années afin que la macro comprenne que si il y a passage d'une année à une autre (année postérieur car mes données sont classées par ordre croissant), cela signifie que la ligne précédant le changement d'année doit être copiée/collée et que le 1er mois de la nouvelle année doit être considéré comme le mois de départ.

    J'ai modifié la macro de la sorte en ajoutant une condition année mais j'ai un bug "Next without for".
    Il semblerait que j'ai oublié un End If mais je ne vois pas où; est ce que qqn sait?

    Le fichier exemple est à l'adresse suivante: http://cjoint.com/?ltltNsZtVo

    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
    Sub Essai()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
        DerLig = 2
        Sheets("Sheet2").Cells.ClearContents
        With Sheets("Sheet1")
            .Cells.Interior.ColorIndex = xlNone
            Y = Year(.Cells(2, 2))
            For Lig = 2 To .Range("B65536").End(xlUp).Row
                YC = Year(.Cells(Lig, 2))
                If YC > Y Or (YC = 2000 And Y = 2009) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    Y = YC
                    M = Month(.Cells(2, 2))
                MC = Month(.Cells(Lig, 2))
                If Y = YC And MC > M Or (MC = 1 And M = 12) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    M = MC
                End If
            Next Lig
        End With
    End Sub
    Merci pour votre aide

  2. #2
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Bonjour,

    C'est un End If qui te manque...
    Tu t'en rendrais coimpte en indentant ton code !...

    (etant précisé que je ne me suis intéressé qu'à la raison du message d'erreur, le reste, surtout non indenté, n'ayant pas été examiné...)

  3. #3
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut modifications
    ucfoutu, je sais bien que c'est un End If qui me manque je l'ai écrit dans mon message

    J'ai placé un End If supplémentaire et après plusieurs tentatives la macro n'a pas donnée d'erreur par contre les conditions ne s'executent plus comme je le veux:

    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
    Sub Reparation_Essai()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
        DerLig = 2
        Sheets("Sheet2").Cells.ClearContents
        With Sheets("Sheet1")
            .Cells.Interior.ColorIndex = xlNone
            Y = Year(.Cells(2, 2))
            For Lig = 2 To .Range("B65536").End(xlUp).Row
                YC = Year(.Cells(Lig, 2))
                If YC > Y Or (YC = 2000 And Y = 2009) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    Y = YC
                    M = Month(.Cells(2, 2))
                MC = Month(.Cells(Lig, 2))
                If Y = YC And MC > M Or (MC = 1 And M = 12) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    M = MC
                    End If
                End If
            Next Lig
        End With
    End Sub
    Désormais je n'obtiens que la dernière date de l'année

    J'ai donc essayé de modifier les conditions:

    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
    Sub Multiple_condition()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
        DerLig = 2
        Sheets("Sheet2").Cells.ClearContents
        With Sheets("Sheet1")
            .Cells.Interior.ColorIndex = xlNone
        M = Month(.Cells(2, 2))
                MC = Month(.Cells(Lig, 2))
            If Y = YC And MC > M Or (MC = 1 And M = 12) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    M = MC
            If Y > YC Or (YC = 2000 And Y = 2009) And MC < M Or (MC = 1 And M = 12) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    M = MC
                        End If
                    End If
                End If
            Next Lig
        End With
    End Sub
    Et maintenat j'obtiens le message d'erreur End If without Block If
    Apparement il faut stopper un End If; comment on fait ça?

  4. #4
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Moi, vois-tu, je me contente à ce stade (et sans préjuger de tout le reste), d'indenter ton code (celui du départ, donc ... le second de ton tout premier message...) selon la règle ...
    J'obtiens ceci :

    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
    Sub Essai()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
      DerLig = 2
      Sheets("Sheet2").Cells.ClearContents
      With Sheets("Sheet1")
        .Cells.Interior.ColorIndex = xlNone
         Y = Year(.Cells(2, 2))
         For Lig = 2 To .Range("B65536").End(xlUp).Row
           YC = Year(.Cells(Lig, 2))
           If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
             If Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
               .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
               DerLig = DerLig + 1
               .Rows(Lig - 1).Interior.ColorIndex = 3
               M = MC
             End If ' <<<=== tu es seul à savoir si tu y veux fin condition1 (et alors il manque la fin de condition2 ou si tu y veux fin condition2 et il manque alors une ligne plus bas pour terminer condition2 !
     
         Next Lig
      End With
    End Sub
    que je soumets à ton examen purement visuel !
    (j'ai, comme tu le vois, mis une ligne en blanc)....
    Tu n'y vois pas une espèce de ... "décalage", toi ?
    Moi oui.
    D'où l'intérêt d'indenter de manière rigoureuse ...

    EDIT ('j'ai rajouté des commentaires à ton code ! Lis-les donc)

  5. #5
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut
    ucfoutu, merci pour ta réponse,

    Je ne suis pas un expert en VBA, loin de là mais au fur à mesure des codes que je lis/modifie je commence (lentement) à comprendre comment cela fonctionne.

    Je voudrai que les deux conditions soient effectives (et donc soient clôturées à la fin du script).
    Si les valeurs répondent à la condition 1, alors la macro doit agir (= extraire dans un nouvel onglet la ligne précédente)
    Si les valeurs répondent à la condition 2, alors la macro doit agir.

    En language statistic, cela revient à dire "condition 1 U condition 2"

    Ce code avait initialement été créé pour une condition unique et je ne sais pas comment clôturé un script avec 2 ou plusieurs conditions.

    Merci par avance pour votre aide,

  6. #6
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Impossible de te répondre ainsi ...
    Reviens sur ton code et commente-le clairement, en précisant om doit se terminer chacune de tes 2 conditions.
    Tu es pour l'instant seul à savoir (tu le sais, j'espère) cette petite chose là, en fonction de ce que tu es également seul à savoir : les instructions conditionnelles concernant chacune de tes deux conditions ouvertes. C'est un minimum pour ne pas nager en pleine eau trouble ...

    EDIT :
    En d'autres termes :
    Commence par nous indiquer quelles sont (ligne par ligne), les seules instruction à exécuter si la condition2 est vraie.

  7. #7
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut
    J'essai de commenter le code:

    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
    Sub Essai()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
      DerLig = 2
      Sheets("Sheet2").Cells.ClearContents
      With Sheets("Sheet1")
        .Cells.Interior.ColorIndex = xlNone
         Y = Year(.Cells(2, 2))
         For Lig = 2 To .Range("B65536").End(xlUp).Row
           YC = Year(.Cells(Lig, 2))
           If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1 - cette condition doit toujours s'exécuter; si à quelqu'endroit de ma feuille de calcul YC>Y alors la ligne -1 doit être copiée/collée (Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig))
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
             If Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2 - cette condition doit toujours s'exécuter; si à quelqu'endroit de ma feuille de calcul YC>Y alors la ligne -1 doit être copiée/collée (Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig))
               .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
               DerLig = DerLig + 1
               .Rows(Lig - 1).Interior.ColorIndex = 3
               M = MC
             End If ' <<<=== tu es seul à savoir si tu y veux fin condition1 (et alors il manque la fin de condition2 ou si tu y veux fin condition2 et il manque alors une ligne plus bas pour terminer condition2 !
     
         Next Lig
      End With
    End Sub

    En fait la macro doit sexécuter de la sorte:

    Vérifier si la condition 1 est respectée. Si oui, alors copier/coller la ligne; si non, alors vérifier si la condition 2 est respectée. Si la condition 2 est respectée, alors copier/coller la ligne; si non alors analyser la ligne suivante.
    Et ainsi de suite jusquà ce que la dernière ligne de ma feuille de calcul ait été analysée.

    La macro doit vérifier à chaque fois si au moins une des deux condition est respectée et si c'est le cas alors elle doit agir (= copier/coller la ligne).

    Peut être que c'est l'écriture de ma macro qui déstabilise; peut être qu'il faut utilise ElseIf la 2ème fois au lieu de If...

  8. #8
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 130
    Par défaut
    Salut derouteu et le forum
    Une bonne indentation permet de savoir où on se situe dans les boucles et tests. Et là, dans ton code :
    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
    Sub Multiple_condition()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
    DerLig = 2
    Sheets("Sheet2").Cells.ClearContents
    With Sheets("Sheet1")
        .Cells.Interior.ColorIndex = xlNone
        M = Month(.Cells(2, 2))
        MC = Month(.Cells(Lig, 2))
        If Y = YC And MC > M Or (MC = 1 And M = 12) Then
            .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
            DerLig = DerLig + 1
            .Rows(Lig - 1).Interior.ColorIndex = 3
            M = MC
            If Y > YC Or (YC = 2000 And Y = 2009) And MC < M Or (MC = 1 And M = 12) Then
                .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                DerLig = DerLig + 1
                .Rows(Lig - 1).Interior.ColorIndex = 3
                M = MC
            End If
        End If
    End If '***************************
        Next Lig '***************************
    End With
    End Sub
    Ça permet de se rendre compte que il y aurait comme un petit problème. pas de for, et un "end if" en trop (lignes avec ******)
    Et je suis loin d'être sûr de comprendre ce que tu veux faire.
    première condition :
    Or est prioritaire sur ET on a :
    (Y = YC And MC > M) Or (MC = 1 And M = 12)
    Il faut que (Y=YC et MC>M) ou bien que (MC=1 et M=12)
    Si les années sont égales, MC doit être supérieur à M si MC est janvier et M décembre, on ne teste pas l'année.

    Comme dans le code on est en cascade, il faut que la première condition soit vrai pour tester la seconde.
    Y > YC Or (YC = 2000 And Y = 2009) And MC < M Or (MC = 1 And M = 12)
    en plus explicite, on a
    [Y>YC] Or [(YC=2000 And Y=2009) And MC<M] Or [(MC=1 And M=12)]
    Mais comme c'est la composé des deux on a :
    {(Y = YC And MC > M) Or (MC = 1 And M = 12)} And{[Y>YC] Or [(YC=2000 And Y=2009) And MC<M] Or [(MC=1 And M=12)]}

    Si (Y = YC And MC > M) =Vrai
    [Y>YC] =Faux
    [(YC=2000 And Y=2009) And MC<M] =Faux
    [(MC=1 And M=12)]=Faux

    si (MC = 1 And M = 12)=Vrai[Y>YC] =Vrai ou Faux
    [(YC=2000 And Y=2009) And MC<M] =Vrai ou Faux
    [(MC=1 And M=12)]=Vrai

    Pour que la seconde condition soit Varie, il faut que
    M=décembre et MC=Janvier

    Ne connaissant pas le but, difficile de corriger (surtout que j'ai pu me tromper, entre autre avec la priorité de l'opérateur OU sur ET, c'est pour ça que je mets des parenthèses).

    Pour les conditions, l'indentation permet de s'y retrouver facilement. Surtout sur des codes longs, avec des boucles et des tests a réponses Vrai et Faux. Même si ça semble faire perdre du temps à la mise en forme, il est facilement comblé par un dépannage plus rapide (quand il y en a besoin).

    Pour les opérateurs, les histoires de priorité implicite m'ont souvent causé des problèmes. Je préfère les expliciter par des parenthèses.
    A+

  9. #9
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Au bout du compte et sans préjudice de l'opportunité ou de l'adresse de tes instructions (qui ne regardent que toi et qui ne sont pas l'objet de ta question) :
    Pour respecter ce que tu nous exposes du mécanisme de tes conditions imbriquées (et uniquement cet aspect là ) :
    Remonte à mon message de 12h54 ... J'y ai mis une ligne en blanc.... (pour déclencher un réflexe, en plus ...)... il te suffit d'y inclure un End If !

  10. #10
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut
    Salut Gorfael et merci pour ta réponse,

    Je pensais que mes explications au début du topic etaient claires, je suis désolé si ce n'est pas le cas.

    Je ne veux pas que les conditions soient en cascade je veux qu'elles s'additionnent les unes aux autres: Vérifier si la condition 1 est respectée. Si oui, alors copier/coller la ligne; si non, alors vérifier si la condition 2 est respectée. Si la condition 2 est respectée, alors copier/coller la ligne; si non alors analyser la ligne suivante.
    Et ainsi de suite jusquà ce que la dernière ligne de ma feuille de calcul ait été analysé.

    Je ne vois pas comment je pourrais expliquer ça autrement. 2 conditions, si l'une d'elle est validée alors la macro doit s'exécuter.

    Je viens de voir dans un vieux code que pour une addition de condition il était approprié d'utiliser If pour énoncer la 1ère condition puis ElseIf pour les conditions suivantes.

    Pour en revenir à MC = 1 et M = 12 Je pensais qu'il s'agissait de la délimitation du périmètre des mois. Autrement dit, énoncer que le 1er mois est le 1 (janvier) et le dernier est le 12(décembre). a partir de cela, la macro sera capable de voir si M <, > ou = à MC

  11. #11
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Je te demande de relire tes deux déclarations contradictoires

    Comme dans le code on est en cascade, il faut que la première condition soit vrai pour tester la seconde.
    Je ne veux pas que les conditions soient en cascade je veux qu'elles s'additionnent les unes aux autres: Vérifier si la condition 1 est respectée. Si oui, alors copier/coller la ligne; si non, alors vérifier si la condition 2 est respectée
    Cela commence à ressembler à du poker javanais ...
    On ne sait plus sur quel pied danser, avec ces deux déclarations ... (j'espère que tu vois pourquoi, y compris en faisant abstraction de tout code)....

  12. #12
    Membre Expert
    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    2 130
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 2 130
    Par défaut
    Salut derouteu et le forum
    Je pensais que mes explications au début du topic etaient claires, je suis désolé si ce n'est pas le cas.
    C'est pas si clair que ça pour moi. Quand on dépanne, et qu'il y a vraisemblablement une contradiction entre le code fournis (qui a des erreurs) et les explications (où on passe sur ce qui semble évident), on est obligé d'interpréter. Et seuls ceux qui ne font rien ne font jamais d'erreur!
    Je ne veux pas que les conditions soient en cascade
    Donc on va partir de ça
    if Condition 1 then
    Traitement 1
    End if
    if Condition2 then
    Traitement 2
    End if
    C'est la manière la plus simple : les condition sont au même niveau et indépendantes l'une de l'autre : On applique le traitement 1 que si la condition 1 est vraie. On applique le traitement 2 que si la condition est vraie. Si les conditions 1 et 2 sont vraies, on applique les traitements 1 et 2
    if Condition 1 then
    Traitement 1
    Elseif Condition2 then
    Traitement 2
    Else
    Traitement 3
    End if
    Si condition 1 est vraie on applique le traitement 1 quelque soit l'état de condition 2
    si condition 1 est fausse et la condtion 2 est vraie on applique le traitement 2
    Si les conditions 1 et 2 sont fausses on applique le traitement 3

    La mauvaise indentation de ton code au moment où j'ai pris le bus ne permettant pas de choisir
    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
            For Lig = 2 To .Range("B65536").End(xlUp).Row
                YC = Year(.Cells(Lig, 2))
                If YC > Y Or (YC = 2000 And Y = 2009) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    Y = YC
                    M = Month(.Cells(2, 2))
                MC = Month(.Cells(Lig, 2))
                If Y = YC And MC > M Or (MC = 1 And M = 12) Then
                    .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
                    DerLig = DerLig + 1
                    .Rows(Lig - 1).Interior.ColorIndex = 3
                    M = MC
                    End If
                End If
            Next Lig
    J'ai opté pour lire bêtement le code :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    If condition 1 Then
         Traitement 1
         If condition 2 then
            Traitement 2
         End if
    End if
    Les condition sont en cascade et la condition 2 ne peut être testée que si la condition 1 est vrai
    A+

  13. #13
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut
    ucfoutu,

    Je n'ai JAMAIS dit "Comme dans le code on est en cascade, il faut que la première condition soit vrai pour tester la seconde"
    C'est Gorfael qui le dit! (fais une recherche sur la page et tu pourras le constater)
    Dans le message suivant celui de Gorfael, je réponds "Je ne veux pas que les conditions soient en cascade"

    Si dans mon code elles apparaissent comme étant en cascade c'est parce que je n'ai pas su comment les écrire autrement parce que je ne suis pas un expert en VBA; ceci est tout au plus ma 4ème macro. DSL

    Ce que je (vous) demande c'est de m'aider à écrire ces conditions pour qu'elles soient indépendantes...
    Car avec ces 2 conditions je compte augmenter l'univers des possibles. Ceux qui répondent à la condition 1 + ceux qui répondent à la condition 2.

  14. #14
    Invité
    Invité(e)
    Par défaut
    Bonsoir,

    Je n'ai JAMAIS dit "Comme dans le code on est en cascade, il faut que la première condition soit vrai pour tester la seconde"
    C'est Gorfael qui le dit! (fais une recherche sur la page et tu pourras le constater)
    Le problème n'est pas que vous ayez dit ou non que dans le code on est en cascade, mais que c'est vrai. Et Gorfael a bien sûr raison.

    Pour qu'il ne le soit pas il faut que le 2ème "If" ne dépende pas du 1er et donc insérer un "End If" avant le 2ème.

    De toute façon comme vous le disent Gorfael et Ucfoutu depuis le début il manque un "End If".

  15. #15
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Re..
    Et un salut à Gorfael et ) Jacques_jean..

    Reprenons ce qui est dit ici :
    Vérifier si la condition 1 est respectée. Si oui, alors copier/coller la ligne; si non, alors vérifier si la condition 2 est respectée. Si la condition 2 est respectée, alors copier/coller la ligne; si non alors analyser la ligne suivante
    Il manque alors un Else If (probablement en renplacement du 2ème If)

    et dans ce cas il ne manquerait pluis le fameux End If manquant...

    Mais on commence vraiment à s'y perdre, dans ce lot d'explications embrouillées (... le reflet d'une pensée claire ?...)


    Et ce serait alors :
    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
    Sub Essai()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
      DerLig = 2
      Sheets("Sheet2").Cells.ClearContents
      With Sheets("Sheet1")
        .Cells.Interior.ColorIndex = xlNone
         Y = Year(.Cells(2, 2))
         For Lig = 2 To .Range("B65536").End(xlUp).Row
           YC = Year(.Cells(Lig, 2))
           If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
           Else If Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             M = MC
           End If          
         Next Lig
      End With
    End Sub
    Mis siu un seul détail supplémentaire est maintenant ajouté aux explications déjà fournies...===>> je laisse tomber définitivement ma participation à cette discussion étrange.

  16. #16
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut
    Bonjour tout le monde et merci pour vos réponses,

    Je pense avoir compris comment créer des conditions dépendantes/indépendantes les unes des autres (et ça c'est déjà un bon point).

    Comme dans mon cas de figure les 2 conditions sont indépendantes je vais utiliser If pour la 1ère et ElseIf pour la 2nde (arrêtez-moi si je me trompe).
    Apparemement le nombre de End If dépend du nombre de If est n'est aucunement impacte par le nombre de ElseIf (arrêtez-moi si je me trompe).
    Il y aura donc un seul End If dans ma macro.

    La structure du code de la dernière macro suggérée par ucfoutu semble donc appropriée:

    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
    Sub Essai()
    Dim Lig As Long, DerLig As Long
    Dim M As Byte, MC As Byte
    Dim Y As Integer, YC As Integer
    Dim i As Long
      DerLig = 2
      Sheets("Sheet2").Cells.ClearContents
      With Sheets("Sheet1")
        .Cells.Interior.ColorIndex = xlNone
         Y = Year(.Cells(2, 2))
         For Lig = 2 To .Range("B65536").End(xlUp).Row
           YC = Year(.Cells(Lig, 2))
           If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
           ElseIf Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             M = MC
           End If          
         Next Lig
      End With
    End Sub
    Ca c'est pour la structure; je vais maintenant devoir travailler sur les conditions car celles-ci ne me renvoient pas les valeurs souhaitées...

    Voici comment je comprends la 1ère condition (corrigez moi svp si je me trompe):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Y = Year(.Cells(2, 2))
         For Lig = 2 To .Range("B65536").End(xlUp).Row
           YC = Year(.Cells(Lig, 2))
           If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
    La macro analyse les lignes entre-elles de la ligne 2 à 65536.
    Condition 1 traite uniquement les années et fait abstraction des mois.
    Si l'année mentionnée dans la seconde ligne est supérieure à l'année mentionnée dans la ligne précédente (If YC > Y) et les années vont de 2000 à 2009 (Or (YC = 2000 And Y = 2009)) alors la macro copie/colle la ligne précédente dans la feuille2 (.Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)) et colore cette même ligne ne rouge dans la feuille1 (.Rows(Lig - 1).Interior.ColorIndex = 3).

    Il semblerait que cette condition fonctionne correctement car j'obtiens bien la dernière date de chaque année.


    Concernant condition 2:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
           ElseIf Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
    Je comprends le code comme ceci:

    Condition 2 traite les années et les mois.
    Si l'année mentionnée dans la seconde ligne est égale à l'année mentionnée dans la ligne précédente (If YC = Y) et le mois mentionné dans la seconde ligne est supérieur au mois mentionné dans la ligne précédente (If MC > M) et les mois vont de 1 à 12 (Or (MC = 1 And M = 12)) alors la macro copie/colle la ligne précédente dans la feuille2 (.Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)) et colore cette même ligne ne rouge dans la feuille1 (.Rows(Lig - 1).Interior.ColorIndex = 3).

    Mais ça ne me renvoit pas les dates à la fin du mois donc j'ai fais une ou plusieurs erreurs

    Est ce que qqn voit ce qui cloche?
    J'ai essaye de changer "And" par "Or" mais ça ne marche pas non plus.

  17. #17
    Inactif  

    Profil pro
    Inscrit en
    Juillet 2007
    Messages
    4 555
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juillet 2007
    Messages : 4 555
    Par défaut
    Bonjour,

    Voilà une seconde question autre que la première (traitée, elle...).
    Isole-la et fais-en une discussion distincte (en n'oubliant pas d'indenter ton code, si tu veux qu'on le regarde).

    EDIT : ta nouvelle question/discussion me parait devoir être du genre :
    J'ai deux dates D1 et D2
    Je souhaite faire deux traitements :
    - traitement 1 : .... (explications claires)
    - traitement 2 : .... (explications claires)

    Et je t'aiderai alors bien volontiers pour résoudre cet autre problème (et peut-être sans tout ce mic mac).

  18. #18
    Invité
    Invité(e)
    Par défaut
    Bonjour,

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
           ElseIf Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             M = MC
           End If
    C'est simple, si vous utilisez "If" puis "Else If", bien évidemment vous n'aurez qu'un "End If" à indiquer, mais le problème n'est pas là.

    Si vous voulez que lorsque les conditions du 1er "If" sont validées, le code soit exécuté et la même chose pour le second "If" il faut séparer les 2 et au bon endroit 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
    19
    20
    21
    For Lig = 2 To .Range("B65536").End(xlUp).Row
           YC = Year(.Cells(Lig, 2))
    
    
    If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             Y = YC
    End If
             Y = YC
             M = Month(.Cells(2, 2))
             MC = Month(.Cells(Lig, 2))
    
    If Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
             .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
             DerLig = DerLig + 1
             .Rows(Lig - 1).Interior.ColorIndex = 3
             M = MC
    End If
    ne donnera pas le même résultat que
    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
     For Lig = 2 To .Range("B65536").End(xlUp).Row
            YC = Year(.Cells(Lig, 2))
     
     
     If YC > Y Or (YC = 2000 And Y = 2009) Then '  <<<<=== condition1
              .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
              DerLig = DerLig + 1
              .Rows(Lig - 1).Interior.ColorIndex = 3
              Y = YC
             M = Month(.Cells(2, 2))
              MC = Month(.Cells(Lig, 2))
    End If
     
    If Y = YC And MC > M Or (MC = 1 And M = 12) Then ' <<<=== condition2
              .Rows(Lig - 1).Copy Sheets("Sheet2").Rows(DerLig)
              DerLig = DerLig + 1
              .Rows(Lig - 1).Interior.ColorIndex = 3
              M = MC
    End If
    Donc il y a plusieurs variantes à envisager dans ce code.

    Un exemple serait quand même le bienvenu pour réussir à comprendre ce que vous voulez en définitive.

  19. #19
    Membre averti
    Profil pro
    Inscrit en
    Mai 2009
    Messages
    28
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Mai 2009
    Messages : 28
    Par défaut
    ucfoutu, jacques_jean,

    Je vais fermer ce topic et le mettre en résolu et en entamer un autre pour la création de la condition.

    Après 18 réponses, il est certain que ça commence à faire long et trop long ce n'est pas bon pour les gens qui viennent rapidement chercher qqs infos sur les forums, c'est indéniable...

    Je vous remercie pour votre aide et à bientôt sur la prochaine discussion

    jacques_jean, vous dites que le placement du If impacte le code; je désirerai des précisions si possible sur le cas de figure précis énnoncé dans votre dernier message.
    Je vais activer/modifier mon compte pour que vous puissez m'envoyer une réponse directement, merci!

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

Discussions similaires

  1. Condition If multiple
    Par M1000 dans le forum ASP
    Réponses: 2
    Dernier message: 01/03/2004, 13h46
  2. [MYSQL] conditions et requetes
    Par sebos63 dans le forum SQL Procédural
    Réponses: 3
    Dernier message: 26/02/2004, 16h41
  3. Condition sur debug et release
    Par xave dans le forum MFC
    Réponses: 3
    Dernier message: 04/02/2004, 15h04
  4. Condition et contenu TImage
    Par Detlev_linux dans le forum Langage
    Réponses: 6
    Dernier message: 23/12/2003, 01h00
  5. boucle avec condition d'arret changeante
    Par NicoH dans le forum Langage
    Réponses: 3
    Dernier message: 10/06/2003, 11h48

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