IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Macros et VBA Excel Discussion :

Filtre sur plusieurs colonnes/lignes [XL-2003]


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 57
    Par défaut Filtre sur plusieurs colonnes/lignes
    Bonjour à tous,

    Alors voilà, j'ai un tableau avec plusieurs fois le même mot (1152P03) sur différentes colonnes et différentes lignes, un peu aléatoirement en fait. Je cherche à faire un filtre qui, quand j'entre le nom "1152P03", cherche et trouve toutes les colonnes et toutes les lignes qui contiennent au moins une fois ce nom... S'il est trouvé, j'aimerais bien sûr que la ligne/colonne entière soit affichée... Je commence à penser à cet algorithme et j'ai besoin de votre inspiration !!!!!!

    Ma fonction me fait penser à un "CTRL-F" mais en plus elle doit filtrer... pas juste trouver les positions dans le tableau...

    Merci de votre aide les copains !

  2. #2
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    dans l'idée, ça donnerait ça

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    Sub RechercheMasque()
    Dim i As Long, MaChaine As String, Cell As Range
    MaChaine = "1152P03"
        With Feuil1
            ' on prend le nombre minimal entre colonnes et lignes utilisées
            ' au delà, la recherche est inutile
            For i = 1 To Application.WorksheetFunction.Min(.UsedRange.Rows.Count, .UsedRange.Columns.Count)
                ' test sur la ligne
                Set Cell = .Rows(i).Find(MaChaine, , xlValues, xlWhole, xlRows)
                If Cell Is Nothing Then Rows(i).Hidden = True
                ' test sur la colonne
                Set Cell = .Columns(i).Find(MaChaine, , xlValues, xlWhole, xlColumns)
                If Cell Is Nothing Then Columns(i).Hidden = True
            Next i
        End With
    End Sub
    Une autre méthode, plus rapide si la plage de données est immense, et de diagonaliser sa recherche au sein du rectangle représentant la plage utilisées :

    1) on part de A1 : recherche en ligne et en colonne
    2) ensuite on se met en B2 : recherche en ligne et en colonne (sans chercher en colonne A et en ligne 1)
    3) ensuite C3 ( sans chercher dans les deux premières colonnes et les deux premières lignes)
    4) Etc .. jusqu'à atteindre le bas de la diagonale

    Mais il y a un peu plus d'écriture de code, puisqu'il faut gérer l'argument After pour justement restreindre et optimiser la recherche au fur et à mesure qu'on avance dans la diagonale

  3. #3
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 57
    Par défaut
    Merci pour la réponse rapide !

    Il me reste à comprendre quelques trucs.
    Pour ce qui est de la plage de données, dans ton bout de code, comment est-elle déclarée ?

    De plus, dans ce cas-ci, est-ce que c'est possible d'entrer le contenu d'une cellule comme référence à la recherche ? Par exemple, si je veux chercher 1152P04, je devrai aller dans le bout de code et le changer, alors que j'aimerais mieux simplement l'écrire dans la feuille excel, dans une cellule quelconque...

  4. #4
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bonjour,

    je ne calcule pas à proprement parler la plage de tes données.

    tout se passe ici :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    For i = 1 To Application.WorksheetFunction.Min(.UsedRange.Rows.Count, .UsedRange.Columns.Count)
    c'est une question de pure logique.
    on va se déplacer de colonne en colonne et de ligne en ligne

    donc on va commencer à la ligne/colonne 1 :

    - colonne A / Ligne 1
    - colonne B / Ligne 2
    - etc...

    ta plage de données sera totalement balayée quand tu auras parcouru X lignes/colonnes ... ce X étant la valeur minimale entre [Nombre de lignes utilisées / Nombre de colonnes utilisées]

    Exemple 1 :

    mes données vont de A1 à Z2000 ==> 26 colonnes et 2000 lignes

    quand j'arrive à la colonne 26, j'ai déjà analysé mes 25 précédentes colonnes (et donc les 2000 cellules de chacune de ces colonnes)
    ==> je n'ai pas besoin d'aller au delà de 26, mes 2000 lignes sont analysées via mes colonnes

    Exemple 2 :

    mes données vont de A1 à D200 ==> 4 colonnes et 2 lignes

    quand j'arrive à la ligne 2, j'ai déjà analysé la ligne précédente (et donc les 4 colonnes de la ligne 1)
    ==> je n'ai pas besoin d'aller au delà de 2, mes 4 colonnes sont analysées via mes lignes



    Ceci étant complètement décortiqué, tu dois maintenant pouvoir deviner la simplification possible de ce code... à laquelle je n'ai absolument pas pensé hier ! (j'ai écris la macro à la volée sans la tester du reste) :

    - regarder si le Nb de lignes et plus important que le nombre de colonnes ==> effectuer un test If/End If
    - en fonction du résultat précédent ==> n'effectuer le Find que sur les colonnes OU les lignes

    tu divises ainsi tes actions par 2



    Concernant le fait d'utiliser une cellule pour récupérer la chaine à détecter, c'est bien sûr possible.
    admettons que ta chaine soit écrite en A1 de la Feuille "Toto"

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MaChaine = Worksheets("Toto").Range("A1").Value

  5. #5
    Membre averti
    Homme Profil pro
    Ingénieur développement matériel électronique
    Inscrit en
    Juillet 2015
    Messages
    57
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 35
    Localisation : Canada

    Informations professionnelles :
    Activité : Ingénieur développement matériel électronique
    Secteur : High Tech - Électronique et micro-électronique

    Informations forums :
    Inscription : Juillet 2015
    Messages : 57
    Par défaut
    Je comprends très bien la logique tu expliques vraiment bien merci beaucoup.

    Si par contre, ma plage de données commence en C13 jusqu'à X.

    J'ai essayé ton code, ça marche nickel, mais j'ai un entête avant ma plage de données, du coup ça efface mon entête lorsque je lance la maccro... En raison de la déclaration de la plage de données...

  6. #6
    Expert confirmé

    Homme Profil pro
    Curieux
    Inscrit en
    Juillet 2012
    Messages
    5 169
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Curieux
    Secteur : Arts - Culture

    Informations forums :
    Inscription : Juillet 2012
    Messages : 5 169
    Billets dans le blog
    5
    Par défaut
    Bon ....

    je retire toute considération logique ... et avoue m'être fourvoyé !

    le raisonnement ne tient pas la route dans certains cas, après avoir testé des situations limites


    ceci devrait être plus confortable ... et cette fois-ci j'ai testé

    vu ma haute perspicacité () sur ce problème, je ne m'aventure pas sur le principe de diagonalisation

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    Sub RechercheMasque()
    Dim i As Long, MaChaine As String, Cell As Range
    Dim DebutLigne As Long
    Dim DebutCol As Long
     
    ' pour définir la limite inférieure
    DebutLigne = 13
    DebutCol = 3
     
    ' la chaine a tester
    MaChaine = Feuil2.[A1].Value
     
    Application.ScreenUpdating = False
        With Feuil1
            ' on commence la boucle à la limite inférieure de la colonne ou de la ligne  et on s'arrête à la valeur supérieure
            For i = Application.WorksheetFunction.Min(DebutLigne, DebutCol) To Application.WorksheetFunction.Max(.UsedRange.Rows.Count, .UsedRange.Columns.Count)
                ' test sur la ligne
                ' on vérifie qu'on est pas avant la première ligne à prendre en compte, et pas après le nombre maximal de lignes de la plage
                If i >= DebutLigne And i < .UsedRange.Rows.Count Then
                    Set Cell = .Rows(i).Find(MaChaine, , xlValues, xlWhole, xlRows)
                    If Cell Is Nothing Then Rows(i).Hidden = True
                End If
     
                ' test sur la colonne
                ' on vérifie qu'on est pas avant la première colonne à prendre en compte, et pas après le nombre maximal de colonnes de la plage
                If i >= DebutCol And i < .UsedRange.Columns.Count Then
                    Set Cell = .Columns(i).Find(MaChaine, , xlValues, xlWhole, xlColumns)
                    If Cell Is Nothing Then Columns(i).Hidden = True
                End If
            Next i
        End With
    Application.ScreenUpdating = True
    End Sub

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [XL-2010] Filtre sur plusieurs colonnes / filtre impossible si cellule vide !!!
    Par le-guedin dans le forum Macros et VBA Excel
    Réponses: 41
    Dernier message: 15/02/2013, 11h29
  2. Filtres sur plusieurs colonnes avec OU
    Par JackIsJack dans le forum Macros et VBA Excel
    Réponses: 5
    Dernier message: 30/05/2011, 17h40
  3. Filtre sur plusieurs colonnes
    Par bellenthan dans le forum Excel
    Réponses: 2
    Dernier message: 10/12/2010, 11h57
  4. Filtre sur plusieurs colonnes
    Par psyskasax dans le forum Modélisation
    Réponses: 9
    Dernier message: 10/03/2009, 12h31
  5. filtre sur plusieurs colonnes en vba
    Par caloumaya dans le forum Macros et VBA Excel
    Réponses: 1
    Dernier message: 31/05/2007, 15h05

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo