Masquer colonne selon couleur en-tête

Bonjour à tous!

Sur ma feuille Base de données, j'ai actuellement 4 boutons me permettant d'afficher/ masquer des colonnes. Cela permet de rendre ma base de données rapidement lisible selon mes attentes.

Pour l'instant le choix des colonnes à afficher/masquer est déterminé sur mes macros par rapport à au rang ou numéro des colonnes. Seulement, la base de données étant amené à évoluer je risque de devoir rajouter ou enlever des colonnes ce qui fausserait le code VBA.

Du coup j'aimerais que le critère de retenu pour masquer mes colonnes devienne la couleur de l'en-tête plutôt que le n° des colonnes, est-ce possible?

Bien cordialement,

43test-ju.xlsm (34.35 Ko)

oui cela est tout à fait possible avec

For I = 1 To Range("IV1").End(xlToLeft).Column
  If Cells(1, I).Interior.Color = 12106214 Then    '12106214  est la couleur rose que vous avez utiliser a adapter pour les autre
    Columns(I).Hidden = True
  End If
Next I

j'ai regarder le fichier et je me pose la question suivante :

pourquoi les colonne 9 à 12 sont cacher aussi alors qu'il sont bleue ???


j'ai modifier un peu le mode pour faire plus simple

la seul vrai méthode que j'ai modifier est "Sub Suivi_des_délais()"

55test-ju.xlsm (31.13 Ko)

Bonjour Nairda, bonjour Minanse.

Etant donné que j'avais également travaillé dessus, je poste ma réponse, qui est du même style que celle de Minanse. Hormis la valeur de la couleur qui diffère (différence dû à la version ?!)

Sub Suivi_des_délais()
Dim i%
With Sheets("Base de données")
    .Columns.Hidden = False
    .Range("d:d, i:l").Columns.Hidden = True
    For i = 1 To .Cells.Find("*", , , , xlByColumns, xlPrevious).Column
        If .Cells(1, i).Interior.Color = 12040422 Then .Columns(i).Hidden = True
    Next i
End With
End Sub

un petit msgbox pour connaitre le code couleur de ta version

Bonjour Nairda,

D'abord une petite révision de tes macros devrait simplifier l'organisation par la suite...

Il faut renommer tes boutons (rectangles), cela se fait facilement dans la zone Nom, à gauche de la barre de formule.

J'ai renommé : "conventions", "échéances", "délais", et la même macro (Masquer) est affectée à ces 3 boutons [c'est la macro qui définira celui qui l'appelle].

(Pour le dernier, pas d'importance, une macro spécifique lui est affectée...)

Pour ton code, si tu peux ne pas sauter de ligne comme tu fais, cela éviterait de courir après pour arriver à le lire, il suffit de l'indenter pour qu'il n'y ait pas de difficulté de lecture...

En ce qui concerne le masquage de colonnes si tu mets Columns(x), cela désigne déjà la colonne entière, et mettre Columns(x).EntireColumn est un pléonasme inutile. Si tu pointait la colonne par une cellule, c'est là qu'il faut le mettre : Range(x, y).EntireColumn...

Ton code actuel réaménagé :

Sub Masquer()
    Dim col, clr&, i%, m%
    Select Case Application.Caller
        Case "conventions"
            col = Array(14, 31)
        Case "échéances"
            col = Array(4, 4, 9, 13, 21, 30)
        Case "délais"
            col = Array(4, 4, 9, 20)
        Case Else
            Exit Sub
    End Select
    Application.ScreenUpdating = False
    Afficher_Tout
    With ActiveSheet
        For i = LBound(col) To UBound(col) Step 2
            For m = col(i) To col(i + 1)
                .Columns(m).Hidden = True
            Next m
        Next i
    End With
    Application.ScreenUpdating = True
End Sub

Sub Afficher_Tout()
    ActiveSheet.Columns.Hidden = False
End Sub

Pour basculer à un système basé sur la couleur de l'en-tête, il faut que tu ajustes tes couleurs en conséquence des découpage à faire.

Pour chaque opération (conventions, échéances, délais), il faut que tu indiques une colonne de référence pour la couleur d'en-tête qui correspondra aux colonnes à masquer (éventuellement plusieurs s'il y a des recoupements comme actuellement, mais à toi de définir un système de couleurs fonctionnel). Dans chaque cas, on identifiera les couleurs et on pourra procéder au masquage en fonction de la couleur. La structure de la macro actuelle n'en sera pas modifiée, mais le contenu oui !

J'ai déjà inséré une variable pour prélever la couleur, mais tes masquages ne correspondant pas aux couleurs actuelles, et si comme il est probable il y aura des recoupements (c'est le cas actuel), ton système réclamera plus de couleurs et plusieurs seront à masquer selon les cas...

A suivre...

Cordialement.

31nairda-test-ju.xlsm (31.16 Ko)

Bonsoir,

Merci à tous pour vos réponses, en plus de fonctionner elles s'exécutent plus vite que mon essai laborieux!

Minanse, effectivement je n'ai pas encore changé les couleurs pour le tri mais ça ne saurait tarder .

MFerrand, votre révision à l'air top! Elle évite l'accumulation de macro et s'exécute instantanément.

Je pourrais m'en contenter mais je ne suis pas sur de la comprendre et ça m'embête! De plus j'ai envie d'y intégrer la solution de minanse pour les couleurs.

Voici ce que je pense avoir compris de votre Code :

Select Case Application.Caller

Case "conventions"

'sert à faire en sorte que la macro "sache" lequel des boutons l'appel

col = Array(14, 31)

' pour chaque bouton, on défini un tableau qui lui correspond, ici : colonne 14 à 31

Application.ScreenUpdating = False

Afficher_Tout

'on empêche la mise à jour de l'écran (parce qu'elle fait perdre du temps?) puis on lance la macro Afficher_tout

For i = LBound(col) To UBound(col) Step 2

'soit i = toute les colonnes de mon tableau prédéfini (Array colonne la plus faible à la plus grande?).

Step 2???

For m = col(i) To col(i + 1)

.Columns(m).Hidden = True

'masque une colonne de plus que mon tableau prédéfini???

Je suis vraiment pas sur de moi, quelqu'un peut-il m'expliquer et me corriger? Désolé pour la perte de temps, je viens de commencer à m'intéresser à VBA et je suis une bille

Merci d'avance,

Pas le temps pour des explications détaillées tout de suite, mais :

Caller renvoie dans ce cas le nom de l'objet Shape qui a appelé la macro. On peut donc distinguer quel bouton a appelé.

On constitue pour chaque cas un tableau qui alterne colonne de début et colonne de fin pour chaque groupe à masquer, d'où la boucle de pas (step) 2 pour pointer la colonne début, dans laquelle une boucle imbriquée masque les cellules de colonne de début à colonne de fin.

Pour les couleurs, le principe de départ est le même, mais on va préalablement déterminer à partir de couleurs, quelles sont les colonnes à masquer. Cela se fait en récupérant la valeur de la couleur d'une cellule de référence prédéfinie dans une variable (plus souple que de s'amuser à aller chercher la valeur de chaque couleur utilisée pour la saisir, et te permet de modifier des couleurs sans toucher au code...). Le tout est que tu définisses les couleurs (car il peut y en avoir plusieurs pour chaque cas de masquage, et certaines couleurs peuvent intervenir dans plusieurs cas, tel que j'ai vu ton fichier actuel) en fixant une cellule de référence pour chaque couleur, permettant d'identifier toutes les colonnes de la couleur. Ensuite le masquage se déroule de la même façon.

Cordialement.


Pour illustrer ton découpage actuel fait apparaître 5 groupes qui devraient être dotés de couleurs distinctes (et une 6e pour les colonnes ne faisant partie d'aucun groupe)

1) col. 4

2) col. 9 à 13

3) col. 14 à 20

4) col. 21 à 30

5) col. 31

et seraient à masquer :

  • conventions: gr. 3, 4, 5
  • échéances: gr. 1, 2, 4, 5
  • délais: gr. 1, 2, 3
(Chaque groupe de colonnes est à masquer dans 2 cas sur 3...)

Bonjour MFerrand,

J'ai défini les couleurs des groupes de colonnes qui serviront au masquage. J'ai rajouté 2 couleurs sur des colonnes vide en prévision de données supplémentaires.

Pour les couleurs ça donne :

1) Col 4, 9 à 13

2) Col 14 à 20

3) Col 21 à 29

4) Col 30

5) Col 31

Et il faudrait effectivement masquer :

conventions : 2),3),4),5)

échéances : 1),3),4),5)

délais : 1),2),4),5)

Si j'ai bien compris il faudrait identifier dans chaque "case" les cellules de référence ayant pour couleur les colonnes à masquer?

Genre Case "conventions"

couleur=Range("N1" ).Interior.ColorIndex and couleur=Range("U1" ).Interior.ColorIndex and couleur=Range("AD1" ).Interior.ColorIndex and couleur=Range("AE1" ).Interior.ColorIndex

En vérité je vois bien ce que tu veux faire mais je ne sais absolument pas comment le mettre en oeuvre

23test-ju.xlsm (35.79 Ko)

Bonjour,

Réveil quelque peu tardif aujourd'hui, ce n'est pas inhabituel mais je peux le mettre au compte de l'anesthésie pour cette fois !

Avalanche de messages à lire et éventuellement répondre... d'où je ne me suis pas encore penché sur ton fichier mais ça va venir...

Bonne journée (quoi qu'elle tire déjà à sa fin).

Bonsoir,

Après réflexion, il m'a paru que s'appuyer sur une cellule de référence pour la couleur était une fausse bonne idée... car ton idée départ étant de pouvoir apporter des modifications susceptibles de déplacer les colonnes, les références seraient également susceptibles d'être déplacées et il faudrait à chaque fois rectifier avec de nouvelles références.

Ce qui m'a paru plus stable c'est l'ordre d'apparition des couleurs dans la ligne. Et au cas où une modification serait apportée à cet ordre, ou introduction d'une nouvelle couleur, les ajustements à faire seraient plus léger.

L'ordre des couleurs correspond à ton ordre : 1 2 3 4 5 (puisque tu les as relevées dans l'ordre !) à ceci près que la couleur non impliquée dans les masquages va venir naturellement en premier, mais en constituant un tableau de couleurs, cette première couleur aura l'indice 0 et les 5 couleurs suivantes les indices 1 à 5. On retombe donc parfaitement sur nos pieds.

On va constituer ce tableau de couleurs avec une fonction :

'Couleurs : non masqué=0 - conventions=2 3 4 5 - échéances=1 3 4 5 - délais=1 2 4 5
Function Couleurs()
    Dim d As Object, clr, i%
    Set d = CreateObject("Scripting.Dictionary")
    With Worksheets("Base de données")
        For i = 1 To .Cells(1, 1).End(xlToRight).Column
            clr = .Cells(1, i).Interior.Color
            d(clr) = ""
        Next i
    End With
    Couleurs = d.keys
End Function

J'ai mis un rappel de ta répartition en commentaire, comme aide-mémoire.

On utilise le dictionnaire pour constituer ce tableau : on défile les cellules de la ligne 1 et on crée pour chacune un élément de dictionnaire avec comme clé la valeur de couleur. On n'a pas à se préoccuper du reste, il ne peut y avoir de doublon dans les clés d'un dictionnaire, et à la fin on aura 6 éléments correspondants aux 6 couleurs qu'on renvoie sous forme de tableau et qui seront classées dans l'ordre de création... Bien pratique, d'autant que le dictionnaire est extrêmement rapide.

Pour Masquer, on n'a comme prévu que peu de bouleversements.

La variable clr devient de type Variant, car elle va accueillir le tableau de couleurs (et non plus une seule). Une variable k (Variant) est rajoutée qui nous servira au départ à faire des tableau (avec Array) selon le bouton cliqué.

Ces tableaux sont ceux que tu as défini : (2, 3, 4, 5) - (1, 3, 4, 5) - (1, 2, 4, 5)

Au cas donc où des modifications affecteraient l'ordre des couleurs, les seules modifications à apporter à la procédure concernent ces tableaux (qui sont au début et facilement modifiables...)

Ceci fait, on charge le tableau de couleurs (en appelant la fonction précédemment créée), puis phase intermédiaire qui intervient : on défile les cellules de la ligne 1 et si sa couleur correspond à l'une des couleurs à masquer (définies dans k, d'où 2 boucles imbriquées) on la note dans la variable col qui nous servira au masquage proprement dit (après qu'on l'ait transformé en tableau avec Split). On a donc cette phase préparatoire qui s'ajoute mais en même temps le masquage s'en trouve allégé puisque la variable col a été apprêtée pour qu'on n'ait besoin de rien d'autre.

Sub Masquer()
    Dim col, clr, k, i%, m%
    Select Case Application.Caller
        Case "conventions"
            k = Array(2, 3, 4, 5)
        Case "échéances"
            k = Array(1, 3, 4, 5)
        Case "délais"
            k = Array(1, 2, 4, 5)
        Case Else
            Exit Sub
    End Select
    clr = Couleurs()
    Application.ScreenUpdating = False
    Afficher_Tout
    With ActiveSheet
        For i = 1 To .Cells(1, 1).End(xlToRight).Column
            For m = 0 To UBound(k)
                If .Cells(1, i).Interior.Color = clr(k(m)) Then
                    col = col & " " & i
                    Exit For
                End If
            Next m
        Next i
        col = Split(Trim(col))
        For m = 0 To UBound(col)
            .Columns(CInt(col(m))).Hidden = True
        Next m
    End With
    Application.ScreenUpdating = True
End Sub

Et le fichier (je le passe après car j'ai déjà eu des incidents avec perte du message, mais qui ne se produisent qu'en cas de message long accompagné de fichier...).

Cordialement.

40nairda-test-ju.xlsm (34.31 Ko)

Bonjour MFerrand,

Cette macro est dingue, Merci !

Elle correspond totalement à mes attentes pratique. J'ai bien compris comment la modifier (le début en tout cas) si je veux ajouter d'autres boutons affectant de futures couleurs . Et pour l'ajout de colonne avec couleur existante, ça marche niquel.

Seule (petite) modification que j'ai faite est d'appeler la macro Afficher_Tout avant Couleurs :

'clr = Couleurs()

Application.ScreenUpdating = False

Afficher_Tout

clr = Couleurs()

Sans ça, le dictionnaire ne remplissait pas son rôle lorsque les colonnes étaient masquées. L'indice n'apparaissait pas dans la ligne If .Cells(1, i).Interior.Color = clr(k(m)) Then lorsque je passais d'un bouton masquer à un autre sans afficher tout.

Encore merci pour le temps passé à m'aider, le résultat est top et j'ai beaucoup appris grâce à vos explications!

Sujet clos

Bien vu ! J'avais pas complètement testé ! Merci.

Rechercher des sujets similaires à "masquer colonne couleur tete"