Créer un recap de plusieurs feuilles

Résolu/Fermé
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 - 19 nov. 2013 à 11:57
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 - 20 nov. 2013 à 15:55
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

pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
19 nov. 2013 à 13:12
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

0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
19 nov. 2013 à 13:42
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.
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
Modifié par pijaku le 19/11/2013 à 13:51
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.
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
19 nov. 2013 à 17:17
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.
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
19 nov. 2013 à 17:24
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!
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
19 nov. 2013 à 17:30
Merci!
0

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

Posez votre question
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 07:50
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...
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
20 nov. 2013 à 10:16
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,
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 10:36
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?
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
20 nov. 2013 à 11:00
L'idéal serait évidemment que les lignes vides ne soient pas copiées.
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 11:14
Je regarde ça dès que j'ai 10 minutes.
Une réponse dans la journée.
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 12:24
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
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
20 nov. 2013 à 13:09
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.
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 13:11
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!!
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
20 nov. 2013 à 14:32
Voilà, je t'ai préparé un nveau doc,
https://www.cjoint.com/?3KuoExEdypz
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 15:25
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...
0
noceb Messages postés 14 Date d'inscription vendredi 6 septembre 2013 Statut Membre Dernière intervention 20 novembre 2013 1
20 nov. 2013 à 15:50
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.
0
pijaku Messages postés 12259 Date d'inscription jeudi 15 mai 2008 Statut Modérateur Dernière intervention 9 août 2022 2 703
20 nov. 2013 à 15:55
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.
0