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 :

Extraire une liste sans doublon


Sujet :

Macros et VBA Excel

  1. #1
    Membre régulier Avatar de Markos22
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2016
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2016
    Messages : 198
    Points : 84
    Points
    84
    Par défaut Extraire une liste sans doublon
    Bonjour,

    J'ai un tableau de plus de 40.000 lignes dont chaque ligne représente une facture. Chaque facture est attribuée à une entreprise, qui dépend d'un groupe. Il peut y avoir toute une série de factures par entreprise.

    J'ai créé un Userform qui permet de générer des listes de factures déjà formatées. J'aimerais qu'on puisse sélectionner les factures par groupe. Je dois donc alimenter les items d'une liste déroulante, de façon à ce qu'il liste les noms des groupes, par ordre alphabétique et sans doublon. Après m'être cassé la cervelle avec l'enregistreur de macros, utilisant l'extraction sans doublon d'excel sur une feuille à part, etc., je me suis dit qu'il vaudrait peut-être mieux faire tout dans le code, en créant par exemple un Array du genre "Groupe() As String".

    Mais voilà : je suis habitué à des langages où on teste simplement si un élément figure dans un Array, grâce à une méthode de l'objet Array. J'ai l'impression que cette méthode n'existe pas en VBA.
    En regardant sur StackOverflow, j'ai trouvé ceci :
    How to find if an array contains a string

    Mais lorsque j'essaie ce code, où les groupes sont dans la colonne "Groupe" du tableau "Liste_Factures", j'ai une erreur "L'indice n'appartient pas à la sélection" qui pointe sur la ligne 25 :
    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
    Sub Liste_groupes()
    Dim Groupes() As String
    Dim groupe As Range
     
    Workbooks("Factures.xlsx").Activate
     
    For Each groupe In Range("Liste_Factures[Groupe]").Cells
        If groupe.Text <> "" And Not IsInArray(groupe.Text, Groupes) Then
            Groupes(i) = groupe.Text
            i = i + 1
        End If
    Next
     
    For i = 0 To UBound(Groupes)
        Range("A" & i) = Groupes(i)
    Next
     
    End Sub
     
    Function IsInArray(stringToBeFound As String, arr As Variant) As Boolean
     
        IsInArray = False
     
     
        For i = 0 To UBound(arr)
            If arr(i) = stringToBeFound Then
                IsInArray = True
                Exit Function
            End If
        Next
     
    End Function
    Je ne vois pas où est l'erreur. Y a-t-il des façons plus pratiques de manipuler les Arrays/Collections/Listes en VBA ?

    Merci d'avance de votre aide.

  2. #2
    Expert confirmé Avatar de BENNASR
    Homme Profil pro
    Responsable comptable & financier
    Inscrit en
    Décembre 2013
    Messages
    2 948
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Tunisie

    Informations professionnelles :
    Activité : Responsable comptable & financier
    Secteur : Finance

    Informations forums :
    Inscription : Décembre 2013
    Messages : 2 948
    Points : 5 174
    Points
    5 174
    Par défaut
    Bonsoir
    pour moi je fais de la façon suivante :
    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
    Dim cel As Range
    Dim unique As New Collection
    Dim i As Integer
    On Error Resume Next
    For Each cel In Range("B2:B" & [B65000].End(xlUp).Row)
    If cel.Value <> "" Then
        unique.Add cel.Value, CStr(cel.Value)
        End If
    Next cel
    On Error GoTo 0
    'Remplir les titres des colonnes
    j = 7
    For i = 1 To unique.Count
    Cells(1, j) = unique(i)
    j = j + 1

  3. #3
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut
    Bonjour !

    Citation Envoyé par Markos22 Voir le message
    on teste simplement si un élément figure dans un Array, grâce à une méthode de l'objet Array. J'ai l'impression que cette méthode n'existe pas en VBA.
    En pensant Excel avant VBA :  tout simplement utiliser la fonction de feuille de calculs EQUIV (Application.Match en VBA) …


    Citation Envoyé par Markos22 Voir le message
    j'ai une erreur "L'indice n'appartient pas à la sélection" qui pointe sur la ligne 25
    Normal, la variable passée est non initialisée !


    Un filtre avancé pouvant créer en une seule ligne de code une liste sans doublon …

    ___________________________________________________________________________________________________________
    Je suis Paris, Egypte, Nigeria, New-York, Mogadicio, Barcelone, London, Manchester, Stockholm, Istanbul, Berlin, Nice, Bruxelles, Charlie, …

  4. #4
    Membre régulier Avatar de Markos22
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2016
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2016
    Messages : 198
    Points : 84
    Points
    84
    Par défaut
    Merci BENNASR. Je ne connais pas bien l'objet Collection de VBA (en fait, je ne le connais pas du tout. Je sais que ça existe, c'est tout). Il ne me reste plus qu'à voir comment trier ça par ordre alphabétique et, subsidiairement, de mettre tout en majuscules, et enfin de le mettre dans la combobox. Je ne suis pas sorti d'affaire !

    Ça va me prendre du temps, mais je devrais maintenant avoir les éléments pour le faire...

  5. #5
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut




    Utiliser alors directement l'ActiveX SortedList, voir les exemples dans les discussions de ce forum …

  6. #6
    Membre régulier Avatar de Markos22
    Homme Profil pro
    Développeur Java
    Inscrit en
    Juillet 2016
    Messages
    198
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 60
    Localisation : France, Val d'Oise (Île de France)

    Informations professionnelles :
    Activité : Développeur Java

    Informations forums :
    Inscription : Juillet 2016
    Messages : 198
    Points : 84
    Points
    84
    Par défaut
    J'ai réussi (sans SortedList) ! Je jetterai un coup d'oeil à SortedList, pour faire plus propre. Mais mon code fonctionne, il initialise parfaitement mon Userform. Finalement, j'ai bien utilisé une liste des groupes (sans doublon, grâce au code de BENNASR), que j'ai listée dans un onglet "Groupes", et j'ai trié la plage ainsi écrite, puis j'ai ajouté les items à ma combo, et j'ai effacé la plage devenue inutile.

    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
    Dim cel As Range
    Dim Groupes As New Collection
    Dim i As Integer
     
    On Error Resume Next
     
    For Each cel In Range("Liste_Factures[Groupe]").Cells
    If cel.Value <> "" Then
        Groupes.Add cel.Value, CStr(cel.Value)
        End If
    Next cel
     
    On Error GoTo 0
     
    Sheets("Groupes").Activate
     
    'Liste des groupes
    For i = 1 To Groupes.Count
        Cells(i, 1) = Groupes(i)
    Next
     
    'Tri alphabétique
    With Range(Range("A1"), Range("A1").End(xlDown))
        .Sort Key1:=Range("A1")
    End With
     
    'Création de la liste déroulante des groupes
    For Each groupe In Range(Range("A1"), Range("A1").End(xlDown)).Cells
        Combo_Groupe.AddItem UCase(groupe)
    Next
     
    'On efface les groupes
    Range(Range("A1"), Range("A1").End(xlDown)).Clear
    C'est un peu bricolé, mais au moins ça marche !

    Merci à tous pour votre aide.

  7. #7
    Inactif  

    Homme Profil pro
    cuisiniste
    Inscrit en
    Avril 2009
    Messages
    15 374
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Var (Provence Alpes Côte d'Azur)

    Informations professionnelles :
    Activité : cuisiniste
    Secteur : Bâtiment

    Informations forums :
    Inscription : Avril 2009
    Messages : 15 374
    Points : 12 068
    Points
    12 068
    Billets dans le blog
    8
    Par défaut re
    je suis pas sur que la collection te trie dans l'ordre une serie meme pas du tout tout ce qu'elle fait c'est faire peter les doublons
    une sorted list en l'alimentant le reste se fait tout seul si ma memoire est bonne
    il me semble qu'il faut faire comme le dico (exist) sauf que la fonction c'est pas exists mais contains si ma memoire est bonne ou alors c'est l'object arraylist

    les outils externe via system.Collection que tu peux avoir a ta disposition recherche sur google ou autre
    1. CreateObject(“System.Collections.ArrayList”)
    2. CreateObject("System.Collections.Queue")
    3. CreateObject("System.Collections.Stack")
    4. CreateObject(“System.Collections.SortedList”)

  8. #8
    Expert éminent sénior
    Avatar de Marc-L
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Avril 2013
    Messages
    9 468
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Hauts de Seine (Île de France)

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Avril 2013
    Messages : 9 468
    Points : 18 674
    Points
    18 674
    Par défaut
    Citation Envoyé par Markos22 Voir le message
    J'ai réussi (sans SortedList) ! […] et j'ai trié la plage ainsi écrite
    Quitte à utiliser le tri d'Excel alors la plage sans doublon peut se créer en une seule ligne de code via AdvancedFilter
    et le code complet en moins de 10 lignes de code, peut-être même pas 5 !

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

Discussions similaires

  1. Réponses: 4
    Dernier message: 01/11/2017, 15h01
  2. [XL-2007] Récupérer une liste sans doublons
    Par Invité dans le forum Excel
    Réponses: 11
    Dernier message: 19/09/2016, 19h22
  3. Renseigner une liste sans doublon dans une feuille ou dans un userform
    Par ouskel'n'or dans le forum Macros et VBA Excel
    Réponses: 19
    Dernier message: 26/01/2009, 14h54
  4. Réponses: 0
    Dernier message: 16/09/2008, 13h28
  5. Comment gérer une liste sans doublons ?
    Par olibara dans le forum C#
    Réponses: 3
    Dernier message: 17/05/2008, 12h24

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