Boucle For Next imbriquée

Résolu
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012 - 27 juin 2012 à 07:20
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012 - 22 juil. 2012 à 23:58
Bonjour à tous,

j'ai fait une macro qui compare d'abord une cellule d'une colonne à une autre et qui compare ensuite (si la 1ere condition est bonne) une autre cellule d'une autre colonne à 2 autres(la valeur dans la 1ere doit être encadré par les 2 valeurs dans les deux autres). Si toutes les conditions sont remplis on écrit dans une cellule, sinon on incrémentre la boucle.

C'est assez compliqué à s'en faire une image je vous met en pièce jointe un exemple : http://cjoint.com/?0FBhtQ6Ssmj

La macro ressemble à ca :
Sub position()
For i = 2 To Sheets(2).Range("C" & Rows.Count).End(xlUp).Row
    For j = 2 To Sheets(3).Range("A" & Rows.Count).End(xlUp).Row
    
        If Sheets(2).Range("C" & i) = Sheets(3).Range("A" & j) Then
            If Sheets(2).Range("F" & i) >= Sheets(3).Range("B" & j) And Sheets(2).Range("F" & i) <= Sheets(3).Range("C" & j) Then
                Sheets(2).Range("G" & i) = "couche"
            Else: Sheets(2).Range("G" & i) = ""
            End If
    Next j
        
        End If
    Next j

Next i
        
    
End Sub


Le problème est que j'obtiens l'erreur : erreur de compilation Next sans For à la ligne du premier Next j.

Merci de votre aide !

86 réponses

Utilisateur anonyme
3 juil. 2012 à 14:37
Bonjour,

Bin mon vieux, ça c'est de l'imbrication
On en apprend tous les jours (la réinjection des tableaux). Merci ucfoutu
Je vais même garder ce fil de côté !
0
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012
3 juil. 2012 à 14:38
Le code est celui là:

derlign1 = Sheets("Fiche_machine").Range("B" & Rows.Count).End(xlUp).Row 'renvoie la dernière ligne de la colonne B du classeur Fiche_machine
derlign2 = Sheets("Maxituo").Range("A" & Rows.Count).End(xlUp).Row 'renvoie la dernière ligne de la colonne A du classeur Maxituo
Sheets("Fiche_machine").Range("C22:D" & derlign1).ClearContents 'effacer le contenu des action todolist ,retrofit...

tablo1 = Sheets("Fiche_machine").Range("A22:D" & derlign1)
tablo2 = Sheets("Maxituo").Range("A3:K" & derlign2)

For i = 1 To UBound(tablo1)
    For j = 1 To UBound(tablo2)
        If Sheets("Fiche_machine").Range("A1") = tablo2(j, 2) Then
            If tablo1(i, 2) = tablo2(j, 1) Then
                If tablo1(i, 1) = tablo2(j, 5) Then
                    If tablo2(j, 8) <= 14 Then
                        tablo1(i, 3) = tablo2(j, 3)
                    End If
                End If
            End If
        End If
    Next j
Next i

Sheets("Fiche_machine").Range("A22:C" & derlign1) = tablo1
End Sub


Je met en pièce jointe la feuille que je dois remplir. La zone à remplir est sur la premiere feuille en orange. J'ai mis des numéros dedans pour indiquer l'emplacement par rapport à l'ordre des résultats qui répondent au même conditions.
http://cjoint.com/?0GdoLz2JqKh

J'espère que ça suffira comme explication
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
3 juil. 2012 à 14:41
Pas de quoi s'ébaudir, banana32 ...
C'est de la "gnognotte", comparé à une seule injection de quinine par jour (j'y ai "goûté" dans mon jeune âge ... et, crois-moi, ça, c'est dur ...)


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
3 juil. 2012 à 14:48
Glos ploblem , robby98800 :
je comprends bien que "montrer ton classeur" est pour toi plus facile que de t'expliquer, mais voilà : je n'ouvre jamais un classeur que je n'ai pas créé ! (je ne fais courir à ma machine aucun risque. Un classeur est un exécutable)


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0

Vous n’avez pas trouvé la réponse que vous recherchez ?

Posez votre question
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
3 juil. 2012 à 15:52
Bonjour robby98800,

Attention, tu utilises ClearContent qui efface aussi les formules (par contre la mise en forme est gardée). Utilises plutôt :
Sheets("Fiche_machine").Range("C22:D" & derlign1).Value = vbNullString  


Cheyenne
0
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012
3 juil. 2012 à 23:38
Bonjour à tous,

Merci Cheyenne pour l'info j'avais eu quelques problème auparavant avec clearcontent sans comprendre d'où cela venait.

Je vais tenter l'explication :
Actuellement si toutes les conditions sont satisfaites, on remplie tablo1(i, 3).
Il faudrait que si cette cellule est déjà remplies et les conditions sont encore satisfaites on remplie alors tablo1(i+1, 3), et ainsi de suite tablo1(i+2, 3) jusquà tablo1(i+3, 3).
Si c'est pas assez clair, j'expliquerai mieux.
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
4 juil. 2012 à 17:43
Bonjour,

C'est très simple :
Tu peux faire un tableau que tu incrémentes (l'indice correspond à la ligne) à chaque fois que la condition est remplie et tu inscris dans la ligne correspondant à la valeur de l'indice.

Exemple avec un tableau "numLigne" :
If ... Then
   numLigne(ligne) = numLigne(ligne) + 1
   if numLigne(ligne) < 4 then  
      tablo1(i + numLigne(ligne) -1, 3) = tablo2(j, 3)
   End If
End If


Cheyenne
0
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012
5 juil. 2012 à 07:41
Bonjour,

Je l'ai placé comme ceci dans la macro :
derlign1 = Sheets("Fiche_machine").Range("B" & Rows.Count).End(xlUp).Row
derlign2 = Sheets("Maxituo").Range("A" & Rows.Count).End(xlUp).Row
tablo1 = Sheets("Fiche_machine").Range("A22:D" & derlign1)
tablo2 = Sheets("Maxituo").Range("A3:K" & derlign2)

For i = 1 To UBound(tablo1)
    For j = 1 To UBound(tablo2)
        If Sheets("Fiche_machine").Range("A1") = tablo2(j, 2) Then
            If tablo1(i, 2) = tablo2(j, 1) Then
                If tablo1(i, 1) = tablo2(j, 5) Then
                    If tablo2(j, 8) <= 14 Then
                        numligne(ligne) = numligne(ligne) + 1
                            If numligne(ligne) < 4 Then
                                tablo1(i + numligne(ligne) - 1, 3) = tablo2(j, 3)
                            End If
                    End If
                End If
            End If
        End If
    Next j
Next i

Sheets("Fiche_machine").Range("A22:C" & derlign1) = tablo1


J'obtiens l'erreur "Sub ou fonction non définie" à cette ligne numligne(ligne) = numligne(ligne) + 1.
J'ai essayé de rentrer numligne comme un tableau fixe mais ça n'a rien donné.
Comment faut-il le rentrer?
Merci
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
5 juil. 2012 à 12:41
Bonjour,

As-tu au moins déclaré les variables et tableaux utilisés et comment ?

"ligne" représente ici le n° de la ligne, autrement dit l'indice de la boucle i.
J'ai écrit "ligne" afin d'être plus explicite et toi tu as collé le code sans réfléchir ni même l'analyser.
Tu vois bien que la variable "ligne" ne reçoit aucune valeur, cela aurait dû te mettre la puce à l'oreille... Un peu d'effort, que diable !

As-tu au moins compris l'utilité du tableau numLIgne et la manière de le renseigner ?

Cheyenne
0
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012
6 juil. 2012 à 07:10
Bonjour,

Oui j'avoue je n'ai pas été très fin sur ce coup là.
J'ai finalement rempli le tableau comme ceci
Sub Fichemach()

Dim numligne(3) As Integer
Dim i As Long
Dim j As Long

derlign1 = Sheets("Fiche_machine").Range("B" & Rows.Count).End(xlUp).Row
derlign2 = Sheets("Maxituo").Range("A" & Rows.Count).End(xlUp).Row
tablo1 = Sheets("Fiche_machine").Range("A22:C" & derlign1)
tablo2 = Sheets("Maxituo").Range("A3:K" & derlign2)
Sheets("Fiche_machine").Range("C22:C" & derlign1).ClearContents

For i = 1 To UBound(tablo1)
    For j = 1 To UBound(tablo2)
       For k = 1 To UBound(numligne)
            If Sheets("Fiche_machine").Range("A1") = tablo2(j, 2) Then
                If tablo1(i, 1) = tablo2(j, 5) Then
                    If tablo1(i, 2) = tablo2(j, 1) Then
                        If tablo2(j, 8) <= 14 Then
                            numligne(k) = numligne(k) + 1
                                If numligne(k) < 5 Then
                                    tablo1(i + numligne(k) - 1, 3) = tablo2(j, 3)
                                End If
                        End If
                    End If
                End If
            End If
        Next k
    Next j
Next i

Sheets("Fiche_machine").Range("A22:C" & derlign1) = tablo1
End Sub

Ca fonctionne c'est à dire que quand le premier groupe de conditions est remplie, ils affichent les actions qui en résulte dans les lignes une après l'autre mais quand on change de groupe de conditions les actions ne sont plus affichées.
Bref je pense que c'est assez compliqué à comprendre sans avoir les fichiers. Il y a peut-être un problème dans l'organisation du tableau créé sur ma feuille.
Je vais essayer de voir ce que je peux faire bien que j'y ai dejà passé toute la matinée
Merci,

Robin
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
6 juil. 2012 à 12:21
Bonjour,

Tu n'as pas bien compris la fonction du tableau numLigne et sa dimension ne doit pas être 3 mais derlign1.
La boucle k n'a pas lieu d'être car tu n'utilises pas le tableau numLigne dans les tests. Pourquoi avoir modifié ce que je t'avais indiqué ?
quand on change de groupe de conditions

Réfléchis bien à ce que tu as écrit...
en remplaçant les Then par des And, excepté "numligne(k) < 5", tu comprendras que tu n'as pas plusieurs "groupes de conditions".
Mais il faut mieux, comme tu l'as fait, scinder les conditions par des Then que d'avoir plusieurs test dans la même ligne car tous sont vérifiés en une fois.
Par contre avec Then si le premier test est faux les suivants ne sont pas testés, d'où gain de temps.

Cheyenne
0
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012
8 juil. 2012 à 05:51
Bonjour,

En fait la toute première tentative que j'avais faite était celle-ci :
Sub Fichemach()

Dim numligne(3) As Variant
Dim i As Long
Dim j As Long

derlign1 = Sheets("Fiche_machine").Range("B" & Rows.Count).End(xlUp).Row
derlign2 = Sheets("Maxituo").Range("A" & Rows.Count).End(xlUp).Row
tablo1 = Sheets("Fiche_machine").Range("A22:C" & derlign1)
tablo2 = Sheets("Maxituo").Range("A3:K" & derlign2)
Sheets("Fiche_machine").Range("C22:C" & derlign1).ClearContents

For i = 1 To UBound(tablo1)
    For j = 1 To UBound(tablo2)
            If Sheets("Fiche_machine").Range("A1") = tablo2(j, 2) Then
                If tablo1(i, 1) = tablo2(j, 5) Then
                    If tablo1(i, 2) = tablo2(j, 1) Then
                        If tablo2(j, 8) <= 14 Then
                            numligne(i) = numligne(i) + 1
                                If numligne(i) < 5 Then
                                    tablo1(i + numligne(i) - 1, 3) = tablo2(j, 3)
                                End If
                        End If
                    End If
                End If
            End If
    Next j
Next i

Sheets("Fiche_machine").Range("A22:C" & derlign1) = tablo1
End Sub


Mais cela me renvoit l'erreur d'éxécution 9, l'indice n'appartient pas à la sélection à la ligne [i]numligne(i) = numligne(i) + 1
/i
Je pense que cela pourrait venir du fait que i varie de 1 jusqu'à la fin du tablo1 et que là, i est utilisé pour le tableau numligne.. Je ne sais pas trop à vrai dire.
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
8 juil. 2012 à 06:25
Vous êtes là confrontés avant tout à un problème de conception.
C'était même la raison de mon interrogation (pour plus haut) au sujet de l'affichage lorsque plusieurs résultats.
J'ai bien un idée, mais vous laisse d'abord chercher, s'agissant de conception et non vraiment de code.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
8 juil. 2012 à 07:46
Je vais vous mettre sur la voie de la réflexion.
1) on revient à la demande de robby. Elle était faite sur ces "tenants" :
For i = 1 To UBound(tablo1)
    For j = 1 To UBound(tablo2)
        If Sheets("Fiche_machine").Range("A1") = tablo2(j, 2) Then
            If tablo1(i, 2) = tablo2(j, 1) Then
                If tablo1(i, 1) = tablo2(j, 5) Then
                    If tablo2(j, 8) <= 14 Then
                        tablo1(i, 3) = tablo2(j, 3) '<=== réflexion/décision
                    End If
                End If
            End If
        End If
    Next j
Next i

Arrêtons-nous au commentaire flêché.
Quelle que soit la décision prise si plusieurs occurrences (affichage ligne plus bas ou affichage colonne plus à droite), on ne peut "toucher" au tableau tablo1 sans le redimensionner, etc ... ce qui est à éviter car ne correspondra plus à Sheets("Fiche_machine").Range("A22:C" & derlign1). De plus : si par addition de lignes : véritables acrobaties à n'en plus finir (comment insérer, par exemple, une ligne dans un tableau sans à la fois le redimensionner et décaler vers le bas tout le reste ?).
Moins difficile si par addition de colonnes, mais cela impliquerait alors que la feuille Fiche_machine n'ait au départ aucune colonne remplie au delà de la 3ème !
Evitons alors tout cela (redimensionnements, décalages, etc ...). Pensons à un mécanisme qui récolterait le tout, chaque fois, en cellule (i,3), quitte à revenir ensuite sur la plage traitée. Et comme nous sommes astucieux, pensons à mémoriser (dans notre code) les lignes où multiples résultats. Cela nous permettre de ne revenir que sur ces lignes-là, plutôt que sur toutes les lignes de la plage.
Voilà une jolie petite gymnastique dominicale.
Je vous ai mis sur les starting-blocks . Je vais observer votre course.
Prêts ? ===>> partez !

________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
8 juil. 2012 à 10:37
Bonjour ucfoutu et roby98800,

> ucfoutu, J'avais laissé robby98800 en plan exprès... car je souhaitais le faire réfléchir sur son "groupe de conditions". Sans doute voulait-il dire "au deuxième passage de la boucle".
En effet, lorsqu'une condition est remplie, les lignes qui suivent sont écrasées. Mais il ne s'en ait pas rendu compte, j'ai attendu pour voir.

J'ai bien lu ce que tu lui proposes, cela fait une sacré gymnastique, mais dans ce cas c'est là solution que je n'avais pas jugée bon de mettre en œuvre car, comme tu le dis, cela exige beaucoup trop d'acrobaties. Vu que notre ami ne doit pas être trop expérimenté, je m'en suis abstenu ne voulant pas lui fournir un code prêt à l'emploi qu'il n'aurait pas forcément intégré. Cela dit sans aucune méchanceté.
Plus facile effectivement de mettre les valeurs en colonnes, si aucune colonne n'est remplie au delà de la 3ème !

>robby, représentation en colonnes

  A B C D E F G H
1 * * x 1
2 * * x x x x 4
3 * * x x x x x 8
4 * *
5 * * x x 2

Colonnes AB, les valeurs du tableau
C...G, les nouvelles valeurs correspondant aux conditions du test.
Colonne H, le compteur indiquant combien de fois pour telle ligne la condition a été remplie. Par exemple en ligne 3, tu as les 5 premières valeurs et la condition a été remplie 8 fois.

Remplacer numLign par numCol et le code deviendrait lorsque la condition est remplie :

Dim numCol() As Long
derlign1 = .....
ReDim numCol(derlign1)

'  lorsque la condition est remplie
If tablo2(j, 8) <= 14 Then
   numCol(i) = numCol(i) + 1
   tablo1(i, 8) = numCol(i)  '  total en colonne H
   If numCol(i) < 6 Then
      tablo1(i, 2 + numCol(i)) = tablo2(j, 3)   ' colonnes C...G
   Endif
End If

Je n'ai mis là que les lignes à changer et attention à modifier le Range pour l'injection de tablo1.

Par ailleurs, je ne vois pas la déclaration des tableaux, cela laisse présumer que tu n'utilises pas Option Explicit, grave erreur !!!

Cheyenne
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
8 juil. 2012 à 11:05
Re,

Argghh, trahi par les espaces, quid de l'alignement !!! il faut mettre des espaces insécables (code 0160)

Je recommence :

  A B C D E F G H
1 * * x         1
2 * * x x x x   4
3 * * x x x x x 8
4 * *
5 * * x x       2

Colonnes AB, les valeurs du tableau
C...G, les nouvelles valeurs correspondant aux conditions du test.
Colonne H, le compteur indiquant combien de fois pour telle ligne la condition a été remplie. Par exemple en ligne 3, tu as les 5 premières valeurs et la condition a été remplie 8 fois.

Dis-donc ucfoutu, vu l'heure de tes posts, je te trouve bien matinal, serais-tu un adepte de l'adage "l'avenir appartient à ceux qui se lèvent tôt" ?

Bon dimanche,

Cheyenne
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
8 juil. 2012 à 11:30
Bonjour, cheyenne
serais-tu un adepte de l'adage "l'avenir appartient à ceux qui se lèvent tôt" ?

Pas le choix ! Les poissons aussi, se lèvent tôt. Et mon épouse adore voir ma pêche sur le gril de mon barbecue
Pour le reste (le problème de notre ami robby98800 :
Les acrobaties ont été faites dès le retour de ma pêche. J'ai même choisi l'acrobatie par rajout de lignes (juste la moins simple, pour m'amuser un peu).
Mais je ne vais pas immédiatement lui servir du tout cuit à copier/coller.
Juste une piste supplémentaire :
Là où, dans mon dernier message, j'ai mis un commentaire flêché : si plusieurs valeurs :
- alimenter la cellule (i,3) par toutes ces valeurs, séparées par un retour chr(10)
- alimenter une collection par le numéro de la ligne (uniquement si plusieurs valeurs)
Puis :
1) injecter le tableau (tel qu'il est. Avec, donc, des cellules dont certaines contiennent plusieurs valeurs séparées par un retour charriot)
2) parcourir la collection (qui, je le rappelle, ne contient que les n°s de lignes des cellules à multiples valeurs). Le faire de bas en haut.
Il est alors simple et rapide de :
- "spliter" la cellule concernée (sur chr(10)
- injecter le nombre de lignes nécessaires (ubound du split)
- passer les valeurs multiples (sauf la 1ère) sur les lignes ainsi ajoutées.

C'est ultra-rapide et, pour tout dire, plus long à expliquer (comme je viens de le faire) qu'à coder (cela ne m'a occupé que le temps de frapper avec mes gros doigts la dizaine de très courtes lignes de code nécessaires) .
________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
cs_cheyenne Messages postés 693 Date d'inscription samedi 18 mai 2002 Statut Membre Dernière intervention 17 avril 2017 2
8 juil. 2012 à 13:04
Re,

Ah ! les matins calmes au bord de l'eau...

Excellente idée que de mettre toutes les valeurs
sur la même ligne séparées par un CrLf, cela simplifie grandement les choses.

Si ce n'est déjà fait, bon appétit et attention aux arêtes !

Cheyenne
0
robby98800 Messages postés 64 Date d'inscription mardi 29 mai 2012 Statut Membre Dernière intervention 27 juillet 2012
8 juil. 2012 à 13:16
Bonjour à vous deux,

Je viens de lire vos deux posts et je vous avoue que pour l'instant ce n'est pas forcément évident pour moi. Je vais bien analyser la chose, me documenter et j'attaque demain matin. Il est le soir ici.
Bonne fin de journée, merci pour votre implication.

Robin
0
ucfoutu Messages postés 18038 Date d'inscription lundi 7 décembre 2009 Statut Modérateur Dernière intervention 11 avril 2018 211
8 juil. 2012 à 13:39
et j'attaque demain matin

Et comme j'aime le sport et les sportifs (j'espère que tu en es un vrai) : je vais te laisser "attaquer". Je n'interviendrai à nouveau qu'en fonction des qualités sportives que montrera ton code d'essai.


________________________
Réponse exacte ? => "REPONSE ACCEPTEE" pour faciliter les recherches.
Pas d'aide en ligne installée ? => ne comptez pas sur moi pour simplement vous dire ce qu'elle contient. Je n'interviendrai qu'en cas de nécessité de développ
0
Rejoignez-nous