Créer un recap de plusieurs feuilles [Résolu/Fermé]

Signaler
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
-
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
-
Bonjour,

Mon but serait de créer un recap concernant des données de certaines feuilles.
Donc,
- de faire une boucle sur chaque feuille
- de faire une boucle sur la colonne B de chaque feuille (car certaines feuilles n'ont rien en colonne B), cela ne m'intéresse donc pas de copier
- et si j'ai des données en colonne B, alors je copie la plage B4:G4 sur ma feuille recap.
Mais ma boucle semble infinie... et je n'arrive pas à me "dépatouiller"...

Mon code :
Sub Bouton3_Cliquer()
Dim fl As Worksheet, i As Long
Dim Cell As Range

i = 4
Range("A4:A65536").Font.Bold = True
For Each fl In ActiveWorkbook.WorkSheets
   If (fl.Name = "Home") Or (fl.Name = "Recap_Quantité") Or (fl.Name = "Propriété") Or (fl.Name = "Fonctionnalité") Or (fl.Name = "x") Or (fl.Name = "y") Or (fl.Name = "Listes2") Or (fl.Name = "Listes0") Then
   'Sinon, le nom de la feuille est différente
   Else
        Columns("B:B").Select
        For Each Cell In Selection
            If IsEmpty(Cell.Value) Then
            Else
                With Sheets("Recap_Quantité")
                    .Range("A" & i) = fl.Name ' Nom de la feuille
                    fl.Range("B4:G4" & Range("B65536").End(xlUp).row).Copy Sheets("Recap_Quantité").Range("B" & i)
                    i = i + 1
                End With
            'Exit Sub
            End If
        Next Cell

    End If

Next fl

End Sub

Merci d'avance pour votre aide.

10 réponses

Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Bonjour,

Pourquoi boucler sur toutes les cellules de la colonne B?

Si tu veux savoir si elle est vide, utilises CountA (NBVAL) :
Application.CountA([B:B])

Ce qui te donne :

Sub Bouton3_Cliquer()
Dim fl As Worksheet, i As Long
Dim Cell As Range

i = 4
Range("A4:A65536").Font.Bold = True
For Each fl In ActiveWorkbook.WorkSheets
   If (fl.Name = "Home") Or (fl.Name = "Recap_Quantité") Or (fl.Name = "Propriété") Or (fl.Name = "Fonctionnalité") Or (fl.Name = "x") Or (fl.Name = "y") Or (fl.Name = "Listes2") Or (fl.Name = "Listes0") Then
   'Sinon, le nom de la feuille est différente
   Else
    'Si colonne B est non vide :
        If Application.CountA([B:B]) <> 0 Then
            'Ton copié collé ICI
            'd'ailleurs, il m'a l'air curieux ton copié collé....
            'tu me diras si problème.
        End If
    End If
Next fl

Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
Bonjour Pijaku,

Merci pour ton aide, maintenant ça marche et ça marche pas :)
Le copié collé se fait bien sur ma feuille recap, mais si une feuille a une colonne B vide, elle le copie qd même... c'est peut-être dû à mon copié collé comme tu le disais ? Tu aurais fait ça comment toi ?

Cordialement.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
J'ai commis une petite erreur :
Application.CountA([B:B])
se rapporte à la colonne B de ... la feuille active! Donc, ne se rapporte pas à la colonne B des feuilles fl de ta boucle.
Donc :
Sub Bouton3_Cliquer()
Dim fl As Worksheet, i As Long
Dim Cell As Range

i = 4
Range("A4:A65536").Font.Bold = True
For Each fl In ActiveWorkbook.WorkSheets
   If (fl.Name = "Home") Or (fl.Name = "Recap_Quantité") Or (fl.Name = "Propriété") Or (fl.Name = "Fonctionnalité") Or (fl.Name = "x") Or (fl.Name = "y") Or (fl.Name = "Listes2") Or (fl.Name = "Listes0") Then
   'Sinon, le nom de la feuille est différente
   Else
    'Si colonne B est non vide :
      With fl
        If Application.CountA(.[B:B]) <> 0 Then ' A NOTER : le point devant [B:B]
            'COPIE-COLLE
        End If
      End With
    End If
Next fl

Par contre, je te laisse tester car tu auras certainement un souci avec ton copié-collé. Notamment ta variable
 i 
risque de te poser des soucis.
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
Bon, j'ai fait différent essai tte l'après midi mais rien de concluant...
Oui, le i pose problèmes.
J'ai essayé sur 1 feuille pour voir ce que me donnait :
j = [CountA(B4:B65536)] => cela correspond bien au nbre de lignes remplies en colonne B et ensuite,
je voulais me servir de ce j afin d'avoir la bonne correspondance de lignes entre le nom de ma feuille et les données de la colonne B.
Mais... pas réussi ! et là, je n'y comprends plus rien!!
Merci encore pour les pistes.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
T'inquiète, je ne vais pas te laisser dans la panade.
Là je quitte pour aujourd'hui, faut que j'aille réparer ma totomobile, mais je reviens demain.
Demain matin, fais moi une petite relace sur ce sujet et je reviendrais de bonne humeur t'apporter toute l'aide dont tu auras besoin.
Bonne soirée et...à demain!
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
Merci!
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Bonjour,
Comme promis je reviens.
Parlons un peu de ton copié-collé.

Qu'elles données copier?
Si B est non vide, on doit copier B4:GdernièrelignecolB.
Ok.
Mais bon, y a t'il des lignes vides à ne pas copier?
Faut-il tout simplement copier la totalité?

Ou coller ces données?
Dans la feuille Sheets("Recap_Quantité"), colonne B, à partir de la première ligne vide, je suppose...

tu dis...
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
Bonjour Pijaku,

Merci d'être revenu !
Oui, si non vide en B sur chacune des feuilles, on doit copier-coller ligne jusqu'à G + la hauteur des données.
Oui, il peut y avoir des lignes vides entre les données, mais je pense que ça se fait une fois copier-coller dans feuille "Recap_Quantité", en colonne B, à partir de la première ligne vide. Et en A, je souhaiterai le nom de ma feuille à chaque fois.

Cordialement,
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Que l'on soit bien clair :
Si B est non vide, veux tu que :
- on copie l'intégralité des colonnes B:G, lignes vides comprises
ou
- on ne copie que les lignes non vides des colonnes B à G?
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
L'idéal serait évidemment que les lignes vides ne soient pas copiées.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Je regarde ça dès que j'ai 10 minutes.
Une réponse dans la journée.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Me revoici.

Cette procédure, teste la sur une copie de ton classeur (fais enregistrer sous / un autre nom), au cas ou ça ferait n'importe quoi. je n'ai pas testé car pas eu le temps de préparer un classeur exemple...

Donc, teste ça et dis moi. On peux peut être améliorer la rapidité d'exécution le cas échéant.
Sub Bouton3_Cliquer()
Dim fl As Worksheet, i As Long, drLigfl As Long
Dim TabFeuils(), TabIn()

'ICI, on créé une variable tableau contenant le nom des feuilles à exclure.
    'Tu peux y ajouter toutes celles que tu souhaites.
TabFeuils = Array("Home", "Recap_Quantité", "Propriété", "Fonctionnalité", "x", "y", "Listes2", "Listes0")

Range("A4:A65536").Font.Bold = True
For Each fl In ActiveWorkbook.Worksheets
  'La fonction EQUIV d'Excel permet de rechercher la position d'un élément dans un tableau
  'en VBA cette fonction s'intitule Match et renvoie une erreur quand l'élément ne fait pas partie du tableau
  'On teste donc si Match renvoie une erreur c'est que la feuille doit être traitée...
  If IsError(Application.Match(fl.Name, TabFeuils, 0)) Then
    'Dans la feuille fl
    With fl
      'Si la colonne B n'est pas vide
      If Application.CountA(.[B:B]) <> 0 Then ' A NOTER : le point devant [B:B]
        'COPIE-COLLE
        'Calcul dernière ligne non vide colonne B feuille fl :
        drLigfl = .Range("B" & Rows.Count).End(xlUp).Row
        'On stocke toutes les lignes de fl dans une variable tableau
        TabIn = .Range("B4:G" & drLigfl)
        'On boucle sur toutes les lignes de notre tableau TabIn
        For i = LBound(TabIn, 1) To UBound(TabIn, 1)
          'Si une ligne de la colonne B est non vide, TabIn(i, 1) sera non vide
          If TabIn(i, 1) <> "" Then
            'Si ligne non vide, on copie colle
            .Range("B" & i + 4 & ":G" & i + 4).Copy Sheets("Recap_Quantité").Range("B" & Rows.Count).End(xlUp).Offset(1, 0)
          End If
        Next i
      End If
    End With
  End If
Next fl
End Sub
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
Bon, j'ai testé mais cela ne fonctionne pas bien.
J'ai fait un test sur 3 feuilles remplies.
La récap ne prend pas la 1ère feuille et sur les 2 autres, une seule ligne a été prise en compte.
Pour le nom de ma feuille, il faudrait que TabIn soit à plusieurs dimensions ?

Merci de prendre du temps à mon problème.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Pas de souci.
Peux tu me faire passer ton fichier exemple, ce sera beaucoup plus simple et rapide...
Pour cela, va sur https://www.cjoint.com/ tu créées un lien vers ton fichier exemple et reviens coller ici le lien ainsi créé.
Attention, pas de données confidentielles!!
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
Voilà, je t'ai préparé un nveau doc,
https://www.cjoint.com/?3KuoExEdypz
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Erreur d'inattention de ma part (une fois n'est pas coutume...)
Le copié-collé effectué se basait, naïvement dans ma tête sur une boucle i de 0 à la fin des valeurs du tableau TabIn. Or ce tableau étant multidimensionnel, il commence à l'indice 1.
D'ou mon changement de
 .Range("B" & i + 4 & ":G" & i + 4).Copy
par :
 .Range("B" & i + 3 & ":G" & i + 3).Copy


Sub CreerRecap()
Dim fl As Worksheet, i As Long, drLigfl As Long, drLigRecap As Long
Dim TabFeuils(), TabIn()

'ICI, on créé une variable tableau contenant le nom des feuilles à exclure.
    'Tu peux y ajouter toutes celles que tu souhaites.
TabFeuils = Array("Home", "Recap_Quantité", "Propriété", "Fonctionnalité", "Sécurité", "Environnement", "Listes2", "Listes0")

Range("A4:A65536").Font.Bold = True
For Each fl In ActiveWorkbook.Worksheets
  'La fonction EQUIV d'Excel permet de rechercher la position d'un élément dans un tableau
  'en VBA cette fonction s'intitule Match et renvoie une erreur quand l'élément ne fait pas partie du tableau
  'On teste donc si Match renvoie une erreur c'est que la feuille doit être traitée...
  If IsError(Application.Match(fl.Name, TabFeuils, 0)) Then
    'Dans la feuille fl
    With fl
      'Si la colonne B n'est pas vide
      If Application.CountA(.[B:B]) <> 0 Then ' A NOTER : le point devant [B:B]
        'COPIE-COLLE
        'Calcul dernière ligne non vide colonne B feuille fl :
        drLigfl = .Range("B" & Rows.Count).End(xlUp).Row
        'On stocke toutes les lignes de fl dans une variable tableau
        TabIn = .Range("B4:G" & drLigfl)
        'On boucle sur toutes les lignes de notre tableau TabIn
        For i = LBound(TabIn, 1) To UBound(TabIn, 1)
          'Si une ligne de la colonne B est non vide, TabIn(i, 1) sera non vide
          If TabIn(i, 1) <> "" Then
            'on calcule la dernière ligne de la feuille Recap :
            drLigRecap = Sheets("Recap_Quantité").Range("B" & Rows.Count).End(xlUp).Offset(1, 0).Row
            'on écrit donc en colonne A le nom de la feuille "origine" des données
            Sheets("Recap_Quantité").Range("A" & drLigRecap).Value = fl.Name
            'on copie colle
            .Range("B" & i + 3 & ":G" & i + 3).Copy Sheets("Recap_Quantité").Range("B" & drLigRecap)
          End If
        Next i
      End If
    End With
  End If
Next fl
End Sub


et je t'ai ajouté en colonne A la feuille d'origine des données...
Messages postés
14
Date d'inscription
vendredi 6 septembre 2013
Statut
Membre
Dernière intervention
20 novembre 2013
1
C'est géant !
Par contre, j'ai dû mal à comprendre cette histoire d'indice pour TabIn... Je vais donc chercher et pouvoir avancer!!
Merci encore et bonne continuation.
Messages postés
12251
Date d'inscription
jeudi 15 mai 2008
Statut
Modérateur
Dernière intervention
17 mars 2021
2 620
Cette histoire de TabIn sert juste à diminuer le temps d'exécution de la macro.
En fait, boucler sur les cellules d'une feuille est beaucoup plus long que boucler sur une variable tableau. Le principe est donc de récupérer les valeurs contenues dans la feuille
TabIn = .Range("B4:G" & drLigfl)
, puis de boucler sur la première "colonne" de ce tableau
For i = LBound(TabIn, 1) To UBound(TabIn, 1)
...

Sinon de rien et bonne continuation à toi.