Masquer des colonnes en fonction de leur valeur

Bonjour,

Dans un classeur, j'ai des onglets qui sur la ligne 1 contiennent des numéros d'année, de 1 à 20.

Dans mon premier onglet portant le nom "Centrale", cellule "B23", je connais la dernière année que je souhaite visualiser.

Je souhaiterais dans toutes les feuilles du classeur masquer les colonnes contenant un nombre supérieur à cette valeur dans la ligne 1 (mais pas celles ne contenant pas de nombre, un intitulé texte par exemple)

J'ai écrit le code ci-dessous dans un module mais ça ne marche pas . merci d'avance pour votre aide.

Sub Sauver()

'Protéger les feuilles

Dim DureeRestante As Integer

Dim Sh As Worksheet

DureeRestante = Sheets("Centrale").Range("B23")

For Each Sh In ActiveWorkbook.Sheets

Dim Cel As Range

Dim MaLigne As Range

Set MaLigne = Range("A1:Z1")

If Sh.ProtectContents = True Then

Sh.Unprotect Password:=Motdepasse

End If

MaLigne.EntireColumn.Hidden = False

Application.ScreenUpdating = False

For Each Cel In MaLigne

If Cel > DureeRestante Then

Cel.Columns.Hidden = True

End If

Next Cel

Application.ScreenUpdating = True

Sh.Protect Password:=Motdepasse

Next Sh

End Sub

Bonjour,

essayé avec

Cel.Columns(1).Hidden = True

Bonsoir,

Sub Sauver()
    Dim DRest%, i%, j%
    DRest = Worksheets("Centrale").Range("B23")
    If DRest = 20 Then Exit Sub
    For i = 2 To Worksheets.Count
        With Worksheets(i)
            .Unprotect "Motdepasse"
            .Columns("A:Z").Hidden = False
            For j = 1 To 26
                If IsNumeric(.Cells(1, j)) Then
                    If .Cells(1, j) > DRest Then .Columns(j).Hidden = True
                End If
            Next j
            .Protect "Motdepasse"
        End With
    Next i
End Sub

NB- Pour la prochaine fois, pense à mettre le code cité sous balise code. Eventuellement à l'indenter, c'est mieux pour la lisibilité. Et note que les déclarations de variables se mettent systématiquement en tête de procédure, toutes (on gagne toujours à la longue à respecter les régles...)

Cordialement.

Merci de ton aide SabV.

Malheureusement, pour l'instant je suis même bloqué avant ça :

J'ai une erreur d'éxécution 1004: Impossible de définir la propriété Hidden de la classe Range au niveau de:

"MaLigne.EntireColumn.Hidden = False"

Bonjour,

vous avez attribué une référence d'objet MaLigne à l'intérieur d'une boucle sur chaque feuille

il faudrait écrire la commande de cette manière (avec un point devant range)

Set MaLigne = .Range("A1:Z1")

ou bien

Set MaLigne = Sh.Range("A1:Z1")

aussi lors d'une boucle sur les feuilles il vaut mieux utiliser Worksheets

qui représente les feuilles de calcul uniquement, Sheets représente tous les onglets ( graph ou autre inclue)

et comme a dit MFerrand, les déclarations de variables se mettent systématiquement en tête de procédure

aussi utiliser le bouton "Code" le bouton vert en haut de la fenêtre du message et coller tous code entre ses basises "

ici

"

Sub Sauver()
Dim DureeRestante As Integer
Dim Sh As Worksheet
Dim Cel As Range
Dim MaLigne As Range

DureeRestante = Sheets("Centrale").Range("B23")

For Each Sh In ActiveWorkbook.Sheets
  Set MaLigne = .Range("A1:Z1")

    If Sh.ProtectContents = True Then
        Sh.Unprotect Password:=Motdepasse
    End If

    MaLigne.EntireColumn.Hidden = False

    Application.ScreenUpdating = False

    For Each Cel In MaLigne
        If Cel > DureeRestante Then
            Cel.Columns.Hidden = True
        End If
    Next Cel

    Application.ScreenUpdating = True
    Sh.Protect Password:=Motdepasse
Next Sh

End Sub

Merci beaucoup à tous les 2 pour vos réponses. Et désolé pour le code mal mis en page. j'essaierai de faire mieux la prochaine fois.

La proposition de MFerrand marche nickel mais j'avoue que je ne comprends pas tout dans la construction du code, ni basiquement dans la déclaration initiale des variables avec des "%", ni pourquoi il y a des "if" sans "end if". Mais je vois bien que c'est court et simple.

Je vais aussi essayer de corriger mon propre code avec les indications de SabV voir si j'arrive à faire quelque chose qui marche.

Bien cordialement,

Re,

Explications :

Dim DRest%, i%, j%

% est un caractère de déclaration de type, signifiant As Integer.

Il en existe pour String ($), Long (&), Single (!), Double (#) et Currency (@). Cela permet de raccourcir les déclarations.

If DRest = 20 Then Exit Sub

Comme tu l'as annoncé tes années vont jusqu'à 20, donc si 20, rien à masquer....

Mais c'est une erreur de ma part car dans ce cas il faut démasquer, au cas où... !

Donc supprimer cette ligne et remplacer par :

            .Columns("A:Z").Hidden = False
            If DRest < 20 Then
                For j = 1 To 26
                    If IsNumeric(.Cells(1, j)) Then
                        If .Cells(1, j) > DRest Then .Columns(j).Hidden = True
                    End If
                Next j
            End If

Si tes valeurs changent, il faudra adapter....

    For i = 2 To Worksheets.Count

Avec une boucle For Each... Next, il te fallait exclure la feuille Centrale, pour ne pas risquer d'y avoir un jour des effets inattendus.

Comme tu as précisé qu'elle était en première position, on peut partir de 2 avec une boucle For... Next

        With Worksheets(i)

La mise sous bloc With (on a plusieurs manips à faire dans la feuille) remplace avantageusement une variable en termes de rapidité.

Et même si l'on dispose d'une variable il ne faut pas hésiter à utiliser cette instruction avec.

On ne peut imbriquer des With qui ne réfèrent pas à la même hiérarchie d'objets (si on travaillait simultanément sur 2 feuilles... par exemple), dans ce cas bloc With pour l'une, variable pour l'autre est le bon compromis... [Ici on n'est que sur une feuille à la fois]

                    If IsNumeric(.Cells(1, j)) Then

Ce qui précède ne pose pas de difficulté, on démasque toutes les colonnes de ta plage ciblée...

Le test ci-dessus en parcourant la première ligne est nécessaire, car ta comparaison peut porter sur une valeur String, comparée à une valeur numérique...

Dans un tel cas, Excel et VBA ne réagissent pas pareil : VBA renvoie normalement une erreur d'incompatibilité de type (erreur 13), Excel renvoie toujours VRAI pour texte > nombre (tu peux tester ça dans une cellule...)

Dans les deux cas il vaut mieux donc tester !

Au cas particulier, en renvoyant la valeur de la cellule pour comparer, il semble qu'Excel prévalle, ce qui aurait conduit à masquer tes colonnes à en-tête textuelles...

                        If .Cells(1, j) > DRest Then .Columns(j).Hidden = True

Pas de End If parce que l'instruction est sur une seule ligne de code.

Cordialement.

Merci infiniment de ta pédagogie MFerrand! C'est vraiment très sympa et je me sens (un peu) plus intelligent!

Rechercher des sujets similaires à "masquer colonnes fonction leur valeur"