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
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 = TrueBonsoir,
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 SubNB- 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 SubMerci 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 SubComme 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 IfSi tes valeurs changent, il faudra adapter....
For i = 2 To Worksheets.CountAvec 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)) ThenCe 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 = TruePas 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!