2 votes

Comment masquer des lignes Excel en fonction du critère suivant : toutes les cellules de plusieurs colonnes non consécutives de cette ligne sont vides.

Dans Excel, comment puis-je masquer des lignes si et seulement si toutes les cellules de plusieurs colonnes non consécutives de la ligne sont vides ? Ma feuille de calcul comporte environ 300 colonnes, je ne peux donc pas cliquer sur chacune d'entre elles à chaque fois que je souhaite effectuer cette opération.

J'ai déjà essayé le code VBA ci-dessous, mais il n'autorise pas plus de deux plages. Je vous remercie.

Private Sub Worksheet_Change(ByVal Target As Range)
'Updateby Extendoffice 20160913
Dim xRg As Range
Application.ScreenUpdating = False
    For Each xRg In Range("B1:B825","D1:D825","F1:F825")
        If xRg.Value = "" Then
            xRg.EntireRow.Hidden = True

        Else
            xRg.EntireRow.Hidden = False
        End If
    Next xRg
Application.ScreenUpdating = True
End Sub

0voto

paul bica Points 1300

Essayez ceci


Option Explicit

Private Sub Worksheet_Change(ByVal Target As Range)
    Dim c As Long

    Application.ScreenUpdating = False
    With UsedRange
        For c = 2 To .Columns.Count Step 2
            .AutoFilter Field:=c, Criteria1:="<>"
        Next
    End With
    Application.ScreenUpdating = True
End Sub

0voto

robinCTS Points 4277

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.

SistemesEz.com

SystemesEZ est une communauté de sysadmins où vous pouvez résoudre vos problèmes et vos doutes. Vous pouvez consulter les questions des autres sysadmins, poser vos propres questions ou résoudre celles des autres.

Powered by:

X