Fusion de feuilles

Bonjour,

J'ai un fichier avec 3 onglets

  • 2 onglets identiques dans la présentation
  • 1 onglet de compilation des données des 2 onglets les unes en dessous des autres.
J'ai un bouton de macro qui fait le travail parfaitement mais il colle toutes les données sur la ligne 2.

Pourriez vous me dire comment modifier le code VBA pour qu'il commence toujours la compilation des 2 onglets à la ligne 6 par exemple.

Merci

11compilation.xlsm (37.72 Ko)

Bonsoir,

J'ai un bouton de macro qui fait le travail parfaitement mais il colle toutes les données sur la ligne 2

C'est récurrent les macros qui font parfaitement le travail, mais...!

Si c'est parfait,il n'y aurait pas de question...

En fait, une macro qui s'exécute sans erreur fait simplement ce que le code qu'on a écrit lui fait faire : la tienne commence par effacer les données existantes de la feuille Compilation, puis parcourt les autres feuilles pour en copier les données et les coller sur Compilation les unes à la suite des autres, en commençant ligne 2 qui est la première ligne vide sous la ligne d'en-tête. Enfin elle élimine les lignes dont la colonne A est vide (?).

Si ce n'est pas ce qu'elle doit faire, il faut expressément dire ce qu'elle doit faire, pas à peu près ou par exemple car ce n'est pas clair dans tes propos.

Cordialement.

Bonjour Christian,Hello MFerrand,

j'ai juste corrigé certaines erreurs en respectant ta syntaxe

Sub consolide_onglets()
 Sheets("Compilation").[A1].CurrentRegion.Offset(1, 0).Clear
 For s = 2 To Sheets.Count
   If Sheets(s).Name <> ("Compilation") Then
     [A500000].End(xlUp).Offset(1, 0).Select
     Sheets(s).Range(Sheets(s).[A2], Sheets(s).[A500000].End(xlUp).End(xlToRight)).Copy
     ActiveSheet.Paste
   End If
 Next s
End Sub

Mais comme tu as des tableaux, il vaudrait mieux utiliser ListObjects

Fais le jeu des 7 erreurs pour les trouver (il y en avait au moins 2 importantes)

Hello Steelson ! Tu m'inquiètes avec tes considérations...

Je reprends le code initial du fichier fourni.

Sub consolide_onglets()
    Sheets("Compilation").[A1].CurrentRegion.Offset(1, 0).Clear
    For s = 2 To Sheets.Count
        Range(Sheets(s).[A2], Sheets(s).[A500000].End(xlUp).End(xlToRight)).Copy _
         [A500000].End(xlUp).Offset(1, 0)
    Next s
    On Error Resume Next
    [A:A].SpecialCells(xlCellTypeBlanks).EntireRow.Delete
End Sub

Je me suis juste contenté d'en réajuster l'indentation, un peu perdue lors de copies certainement. Je n'en ai pas changé un seul mot.

Il ne me plait pas spécialement et j'écrirai différemment, mais pour autant, il s'exécute sans erreur, et tes 6 modifications ne rectifient aucune erreur ! ????

Cordialement.

Et en regardant de plus près, le problème de dépendance à la feuille active (erreur si la macro n'est pas lancée à partir de l'onglet Compilation) est conservé par tes modifications.

Hello Steelson ! Tu m'inquiètes avec tes considérations......

Je me suis juste contenté d'en réajuster l'indentation, un peu perdue lors de copies certainement. Je n'en ai pas changé un seul mot.

Il ne me plait pas spécialement et j'écrirai différemment, mais pour autant, il s'exécute sans erreur, et tes 6 modifications ne rectifient aucune erreur ! ????

Ah ben tu as peut-être raison !! sûrement même ... mais lors d'un lancement (peut-être direct de l'éditeur de macro en effet), j'avais eu une recopie de l'onglet Compilation sur lui-même !! j'avais donc introduit d'une part l'exclusion de cet onglet et d'autre part Range(Sheets(s).

Il n'en reste pas moins vrai qu'il est plus élégant (et sans risque) de travailler avec ListObjects

Bonjour à tous,

je propose cette petite adaptation du code de Steelson :

Option Explicit

Sub consolide_onglets()
  Dim s As Byte
  Worksheets("Compilation").[A1].CurrentRegion.Offset(1, 0).Clear
  For s = 2 To Sheets.Count
    With Sheets(s)
      If .Name <> "Compilation" Then
        [A500000].End(xlUp).Offset(1, 0).Select
        .Range(.[A2], .[A500000].End(xlUp).End(xlToRight)).Copy
        ActiveSheet.Paste
      End If
    End With
  Next s
End Sub

mais à partir de 256 feuilles, au lieu de Dim s As Byte mettre : Dim s%

dhany

Mon soucis resterait ceci :

.Range(.[A2], .[A500000].End(xlUp).End(xlToRight)).Copy

car si la dernière ligne n'est pas renseignée complètement, on risque une troncature de la copie

il faut absolument passer à ListObjects

Bonjour à tous,

Le souci était à mon sens que si la macro est lancée sans que Compilation soit la feuille active (car aucun bouton....), le résultat sera alors inattendu, mais c'est la même chose pour les deux versions...

Qu'il soit plus élégant d'utiliser ListObject, sans doute... mais j'attends toujours que l'utilisateur précise ce qu'il voudrait car sa demande aboutirait à introduire des lignes vides dans Compilation, ce qui a-priori est quelque peu incohérent... !?

Cordialement.

MFerrand a écrit :

Le souci était à mon sens que si la macro est lancée sans que Compilation soit la feuille active...

tu as tout à fait raison ! pour cela, la solution est simple : il suffit d'ajouter cette ligne en début de macro :

If ActiveSheet.Name <> "Compilation" Then Exit Sub

OU même (au choix) :

Worksheets("Compilation").Select

dhany

Je persiste à trouver qu'il mieux de proscrire l'utilisation de Select et en contrepartie de qualifier systématiquement les expressions renvoyant un objet.

* oui, mais d'un autre côté faut pas oublier non plus que si on doit absolument sélectionner la cellule d'une feuille, on est obligé d'aller dessus, par Worksheets("FeuilX").Select ou par Worksheets("FeuilX").Activate

si t'as une méthode pour sélectionner une cellule d'une feuille sans être sur cette feuille, je suis très fortement preneur ! bien sûr, toujours dans le cas où la sélection est obligatoire ; par exemple si on veut être sur cette cellule en fin de macro afin que l'utilisateur puisse y saisir quelque chose : ça a donc le gros avantage de se positionner directement dessus ; on peut même utiliser au besoin, par exemple :

Application.GoTo [AW200], True

mais là aussi, ça marche que pour la feuille active.


* de plus, j'utilise souvent Worksheets("FeuilX").Select pour aller sur la feuille quand on veut y voir les résultats de la macro mais si t'as une méthode pour voir les résultats d'une feuille sans aller dessus, je suis preneur ! j'ai pas la vue à rayons X de superman pour voir une feuille au travers des autres !

* enfin, c'est très souvent que j'utilise en début de macro une des 2 méthodes de mon post précédent pour simplifier les références pour la feuille active : dès lors, inutile de mettre une référence explicite à la feuille puisqu'étant dessus, toutes les références sans nom de feuille explicite sont pour cette feuille active.


de la même façon que l'Enregistreur de macros « en met toute une une tartine » pour un job d'une seule instruction, il faut comprendre en lisant l'aide VBA que quand des références commencent par

Workbooks("Nom du classeur").Worksheets("Nom de feuille")

c'est absolument pas obligatoire si le classeur en cours est le classeur actif, et si la feuille en cours est la feuille active : c'est juste une bonne indication au cas où c'est pas le cas ; donc ensuite, c'est au programmeur de gérer correctement les feuilles.

dhany

1) Aller voir le résultat : ça se passe à la fin ! Jusque là on a juste besoin de rien voir ! c'est plus rapide...

2) Chaque fois qu'on ne cible pas explicitement un objet, on le fait chercher par VBA à partir de Application. C'est sans doute négligeable au niveau classeur dès lors qu'un seul est utilisé et qu'il n'y aura pas concurremment plusieurs classeurs ouverts simultanément, mais pour les feuilles une telle situation est rare et on ne peut préjuger de l'avenir, et la désignation de la feuille, y compris sous la forme ActiveSheet est toujours préférable à aucune, de même que l'utilisation de With dès lors que le nombre de fois que l'on a à s'y référer est supérieur à 1, donc dès 2, est un facteur d'accélération de l'exécution.

Et je ne connais aucun cas qui justifie de sélectionner une cellule pour opérer une quelconque action autre que la sélection !

Cordialement.

on s'est croisés ; j'ai complété mon post précédent ; moi, la plupart du temps, j'utilise un seul classeur à la fois.

Pas vu en quoi consistait ta modification, mais rien à changer à ce que j'ai écrit parès relecture...

Ce que l'on souhaite comme affichage après obtention du résultat, ça se passe à la fin...

Et la qualification des plages (non nommées, car si nommées leur désignation inclut la feuille), je l'opère également dans les évènementielles pour cibler la feuille concernée avec Me, car en ne le précisant pas on fait chercher comme toujours la feuille active...

NB- Je n'ai jamais utilisé l'enregistreur pour produire une macro, depuis mes débuts avec VBA, mais je commence à bien connaître les dégats que cela provoque dans la manière de coder des novices qui ont cru bon de commencer avec l'enregistrement de macros...

j'évite toujours l'Enregistreur de macros, sauf que parfois, il est bien utile pour se rappeler quelle instruction VBA utiliser quand on l'a oubliée, ou si on la connaît pas. y'a tellement d'choses dans l'VBA, c'est difficile de tout connaître par cœur, pas vrai ?

dhany

sauf que parfois, il est bien utile pour se rappeler quelle instruction VBA utiliser quand on l'a oubliée, ou si on la connaît pas.

J'ai bien dit pour produire une macro ! Elucider un point de sysntaxe est par contre une bonne utilisation de l'enregistreur... (bien qu'il ne soit pas toujours en mesure de rendre ce service, voir du côté des Shapes...)

MFerrand a écrit :

Le souci était à mon sens que si la macro est lancée sans que Compilation soit la feuille active...

tu as tout à fait raison ! pour cela, la solution est simple : il suffit d'ajouter cette ligne en début de macro :

If ActiveSheet.Name <> "Compilation" Then Exit Sub

OU même (au choix) :

Worksheets("Compilation").Select

dhany

Cela m'a turlupiné cette affaire ... mais j'ai la réponse ! Dans tous les cas il faudrait exclure la feuille compilation ! Il n'y a pas de conséquence car la feuille vide se copie ici sur elle-même !

Mais elle était exclue par sa position en 1, avec la boucle commençant à 2 !

Tu as raison, je n'avais pas fait attention !

For s = 2 To Sheets.Count
Rechercher des sujets similaires à "fusion feuilles"