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 :

Boucle "For Each" mal construite [XL-2019]


Sujet :

Macros et VBA Excel

  1. #1
    Membre averti
    Homme Profil pro
    Data_Analyst
    Inscrit en
    Décembre 2020
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Data_Analyst

    Informations forums :
    Inscription : Décembre 2020
    Messages : 32
    Par défaut Boucle "For Each" mal construite
    Bonjour,

    Je viens vous demander de l'aide car je suis vraiment coincé, je ne trouve pas la solution !

    Voici le code de mon bouton :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    Private Sub CommandButton1_Click()
    Dim cell, cell1, cell2, plage1, plage2 As Range
    Dim num_recherche, indice_ligne As Integer
    Dim w1,w2 As Worksheet
     
    Set w1 = ActiveWorkbook.Worksheets("EXPERTISE (Ecriture)")
    Set w2 = ActiveWorkbook.Worksheets("Tableau")
    num_recherche = w1.Cells(2, 21).Value
     
    For Each cell In w2.Range("A4:A500")
        If cell.Value = num_recherche Then
            indice_ligne = cell.Value
        End If
    Next cell
     
    Set plage1 = Union(w1.Cells(5, 3), w1.Cells(5, 11), w1.Cells(5, 17))
    Set plage2 = Union(w2.Cells(indice_ligne, 8), w2.Cells(indice_ligne, 4), w2.Cells(indice_ligne, 38))
     
    For Each cell1 In plage1
        MsgBox (cell1.Value)
        If cell1.Value <> "" Then
            For Each cell2 In plage2
            MsgBox (cell2.Value)
            cell1.Copy 
            cell2.PasteSpecial Paste:=xlPasteValues
     
    'Idem avec :cell2.Value=cell1.Value
     
            MsgBox (cell2.Value)
            Next cell2
         End If
    Next cell1
     
    MsgBox ("Fin")
    End Sub
    J'ai essayé de mettre des msgbox pour afficher comment travail la boucle mais rien à faire, je n'arrive pas à comprendre.
    Je m'explique :
    J'ai plage1 et plage2 qui sont 2 range avec 3 cellules chacune. Je souhaite juste parcourir les 2 plages, cellule par cellule et si chaque cellule de plage1 est non vide, alors j'attribue sa valeur à la cellule correspondante de la plage 2 (vu que c'est le meme ordre et meme nombre)
    Sauf qu'avec mon code, il a attribué la valeur de la derniere cellule de plage1 aux 3 cellules de plage2.

    Je pense que le For Each imbriqué est mal construit sauf que je ne vois pas comment faire.

  2. #2
    Membre Expert
    Inscrit en
    Décembre 2002
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 946
    Par défaut
    Salut, effectivement , le problème vient du fait que vous avez imbriqué les deux boucles For Each. Dans votre code actuel, pour chaque cellule dans plage1, vous parcourez toutes les cellules de plage2. C’est pourquoi la dernière valeur de plage1 est copiée dans toutes les cellules de plage2.
    Dans ce code, j’ai utilisé un tableau pour stocker les cellules de plage1 et plage2. Ensuite, j’ai utilisé une boucle For pour parcourir les deux plages en parallèle. Si une cellule dans plage1 n’est pas vide, sa valeur est copiée dans la cellule correspondante de plage2.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    Private Sub CommandButton1_Click()
    Dim cell As Range
    Dim num_recherche, indice_ligne, i As Integer
    Dim w1,w2 As Worksheet
    Dim plage1(1 To 3) As Range, plage2(1 To 3) As Range
     
    Set w1 = ActiveWorkbook.Worksheets("EXPERTISE (Ecriture)")
    Set w2 = ActiveWorkbook.Worksheets("Tableau")
    num_recherche = w1.Cells(2, 21).Value
     
    For Each cell In w2.Range("A4:A500")
    If cell.Value = num_recherche Then
    indice_ligne = cell.Row
    Exit For
    End If
    Next cell
     
    Set plage1(1) = w1.Cells(5, 3)
    Set plage1(2) = w1.Cells(5, 11)
    Set plage1(3) = w1.Cells(5, 17)
     
    Set plage2(1) = w2.Cells(indice_ligne, 8)
    Set plage2(2) = w2.Cells(indice_ligne, 4)
    Set plage2(3) = w2.Cells(indice_ligne, 38)
     
    For i = 1 To 3
    If plage1(i).Value <> "" Then
    plage2(i).Value = plage1(i).Value
    End If
    Next i
     
    MsgBox ("Fin")
    End Sub

  3. #3
    Membre averti
    Homme Profil pro
    Data_Analyst
    Inscrit en
    Décembre 2020
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Data_Analyst

    Informations forums :
    Inscription : Décembre 2020
    Messages : 32
    Par défaut Bien vu Franc, merci!
    Bonjour,

    J'ai compris la logique, mais il n'y a pas un autre moyen pour faire un For imbriqué car dans mon cas, ta solution fonctionne très bien sauf que j'ai plus de 100 cellules pour chaque plage, j'ai posé la question avec un code simplifié à 3 cellules.
    Le truc c'est que dans les autres langages de programmation, on fait souvent des boucles imbriqués car ça parcours indice par indice, ex :
    For i=1 to 100
    for j=1 to 100
    do .....
    L'ordinateur parcours i=1, puis j=1, ensuite i=2 et j=2.
    Mais je vois qu'en VBA ce n'est pas ça, il fait i=1 et j=1 jusqu'à 100, puis il fait i=2 et j=1 à 100 ...jusqu'à i=100 et j=100.
    Donc peut-on contourner ce problème ? Sachant que parfois j'ai une plage continue ex Range("G4:L21"), ce qui fait 108 cellules donc il va falloir que je déclare 2 plages avec un indice de 1 à 109 alors que si les boucles:
    Code vba : Sélectionner tout - Visualiser dans une fenêtre à part
    For Each cell in Range("G4:L21")

    fonctionnent pas à pas, ça serait plus pratique. Cela dit, s'il n'y a pas d'autres solutions, et ben je vais me les taper les 108 cellules.
    Au fait, bien vu pour le Exit For, qui sert à sortir de la boucle quand il trouve l'indice_ligne, je ne savais pas non plus qu'on pouvait le faire.
    Merci beaucoup en tout cas!
    Bonne continuation à vous !

  4. #4
    Membre Expert
    Inscrit en
    Décembre 2002
    Messages
    946
    Détails du profil
    Informations forums :
    Inscription : Décembre 2002
    Messages : 946
    Par défaut
    Voici une autre possibilité:

    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
    Private Sub CommandButton1_Click()
    Dim cell As Range
    Dim num_recherche, indice_ligne, i As Integer
    Dim w1,w2 As Worksheet
    Dim plage1 As Range, plage2 As Range
     
    Set w1 = ActiveWorkbook.Worksheets("EXPERTISE (Ecriture)")
    Set w2 = ActiveWorkbook.Worksheets("Tableau")
    num_recherche = w1.Cells(2, 21).Value
     
    For Each cell In w2.Range("A4:A500")
    If cell.Value = num_recherche Then
    indice_ligne = cell.Row
    Exit For
    End If
    Next cell
     
    Set plage1 = w1.Range("G4:L21")
    Set plage2 = w2.Range("A1:E21") ' Remplacez par votre plage2
     
    For i = 1 To plage1.Cells.Count
    If plage1.Cells(i).Value <> "" Then
    plage2.Cells(i).Value = plage1.Cells(i).Value
    End If
    Next i
     
    MsgBox ("Fin")
    End Sub

  5. #5
    Membre averti
    Homme Profil pro
    Data_Analyst
    Inscrit en
    Décembre 2020
    Messages
    32
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 41
    Localisation : France, Rhône (Rhône Alpes)

    Informations professionnelles :
    Activité : Data_Analyst

    Informations forums :
    Inscription : Décembre 2020
    Messages : 32
    Par défaut Merci franc
    Bonjour,

    J'ai compris la logique, c'est quand même mieux de cette manière.

    Cordialement,

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

Discussions similaires

  1. [Toutes versions] Boucle conditionelle : For each next
    Par Kiera dans le forum Macros et VBA Excel
    Réponses: 2
    Dernier message: 07/01/2015, 21h19
  2. Boucle xsl:for-each provoque une erreur
    Par Max1000p dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 05/06/2012, 18h41
  3. Boucle dite "for each"
    Par sebcbien11290 dans le forum Langage
    Réponses: 5
    Dernier message: 19/07/2011, 18h16
  4. [XSLT] Problème de boucle avec for-each
    Par knack8 dans le forum XSL/XSLT/XPATH
    Réponses: 1
    Dernier message: 29/04/2009, 02h42
  5. boucle <xsl:for-each>
    Par Mike35 dans le forum XSL/XSLT/XPATH
    Réponses: 17
    Dernier message: 13/02/2006, 12h58

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