S'il y a beaucoup de colonnes à vérifier, la solution généralisée suivante simplifiera la saisie du code :
Private Sub Worksheet_Change(ByVal Target As Range)
Const strcRowExtent As String = "1:825"
Const strcColExtent As String = "B:BDB"
Dim boolHideRow As Boolean
Dim lngFirstColNumber As Long
Dim rngRow As Range
Dim rngVisibleRowExtent As Range
Dim rngColumn As Range
Dim rngColExtent As Range
Set rngVisibleRowExtent = Range(strcRowExtent).SpecialCells(xlCellTypeVisible)
Set rngColExtent = Range(strcColExtent)
lngFirstColNumber = rngColExtent.Column
Application.ScreenUpdating = False
For Each rngRow In rngVisibleRowExtent.Rows
boolHideRow = True
For Each rngColumn In rngColExtent.Columns
If (rngColumn.Column - lngFirstColNumber) Mod 2 = 1 Then
'Skip every second column
ElseIf rngColumn.Cells(rngRow.Row).Value2 <> "" Then
boolHideRow = False
Exit For
End If
Next rngColumn
If boolHideRow Then Rows(rngRow.Row).EntireRow.Hidden = boolHideRow
Next rngRow
Application.ScreenUpdating = True
End Sub
Explication :
Dans un premier temps, l'ensemble des lignes visibles est extrait de l'ensemble des lignes. Cela permet une amélioration considérable de la vitesse.*
Le code parcourt ensuite cet ensemble de lignes visibles. Pour chaque ligne, il parcourt les colonnes appropriées en vérifiant la présence de valeurs non vides et de valeurs no cache la ligne dès que la première est trouvée. (Le masquage d'une ligne est l'action par défaut qui ne se produit que si toutes les colonnes appropriées sont vides).
EDIT #2 :
Deuxième version (v2.1) qui cache également les colonnes, selon le commentaire de l'OP ci-dessous :
Private Sub Worksheet_Change(ByVal Target As Range)
' v2.1
Const lngcSkipRows As Long = 4
Const strcRowExtent As String = "1:825"
Const strcColExtent As String = "B:BDB"
Dim boolHideRow As Boolean
Dim lngFirstColNumber As Long
Dim rngRow As Range
Dim rngVisibleRowExtent As Range
Dim rngColumn As Range
Dim rngColExtent As Range
Dim rngCol As Range
Dim rngVisibleColExtent As Range
Dim rngCroppedCol As Range
Application.ScreenUpdating = False
' Hide rows
Set rngVisibleRowExtent _
= Range(strcRowExtent).Columns(1).SpecialCells(xlCellTypeVisible).EntireRow
Set rngColExtent = Range(strcColExtent)
lngFirstColNumber = rngColExtent.Column
For Each rngRow In rngVisibleRowExtent.Rows
boolHideRow = True
For Each rngColumn In rngColExtent.Columns
If (rngColumn.Column - lngFirstColNumber) Mod 2 = 1 Then
'Skip every second column
ElseIf rngColumn.Cells(rngRow.Row).Value2 <> "" Then
boolHideRow = False
Exit For
End If
Next rngColumn
If boolHideRow Then Rows(rngRow.Row).EntireRow.Hidden = boolHideRow
Next rngRow
'Hide Columns
Set rngVisibleColExtent _
= Range(strcColExtent).Rows(1).SpecialCells(xlCellTypeVisible).EntireColumn
For Each rngCol In rngVisibleColExtent.Columns
Set rngCroppedCol _
= rngCol _
.Resize(Range(strcRowExtent).Rows.Count - lngcSkipRows) _
.Offset(lngcSkipRows)
If WorksheetFunction.CountA(rngCroppedCol) = 0 Then rngCol.Hidden = True
Next rngCol
Application.ScreenUpdating = True
End Sub
Explication :
Il s'avère que l'extraction de l'ensemble des colonnes visibles lorsqu'il y a des lignes cachées (et vice versa) nécessite une légère modification de la formule d'extraction.
Le code qui parcourt en boucle l'ensemble des colonnes visibles est plus simple que celui qui concerne les lignes, car une boucle intérieure n'est pas nécessaire. La fonction de la feuille de calcul CountA()
est utilisé à la place.
Notez qu'il peut encore sembler y avoir des colonnes non cachées qui sont toutes vides. Ces colonnes contiennent des valeurs dans des lignes masquées. Le fait de ne pas masquer ces colonnes est intentionnel, conformément à votre commentaire.
Note : Si vous êtes curieux de connaître ma convention de dénomination des variables, elle est basée sur les principes suivants RVBA .
* Au prix de la perte de la possibilité d'annuler les lignes masquées automatiquement lors de l'édition de la feuille. Il est possible d'y remédier si nécessaire.