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

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  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 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+

+ 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