[VBA] Supprimer elements communs 2 listes

mrsmith1 -  
pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   -
Bonjour,
je voudrais supprimer tous les elements communs de 2 collections, mais mon code me renvoie une erreur que je ne comprend pas :
For i = 1 To tableau_B.Count
For k = 1 To tableau_B0.Count
If tableau_B0(k) = tableau_B(i) Then
tableau_B.RemoveAt (i)
tableau_B0.RemoveAt (k)
End If
Next k
Next i

Pourtant, j'ai déclarer plus tot les tableau comme étant des variables :
Dim tableau_B As New Collection
Dim tableau_B0 As New Collection

merci beaucoup

3 réponses

  1. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    Pour te donner une réponse complète et adaptée à ton cas, du moins ce que tu nous présente, voici un code d'effacement d'items de collection.
    Il te faut stocker, dans une variable tableau, les item d'une des deux collections pour ne pas bugguer... Effectivement, lors de la suppression, dans ton code du premier tableau_B.Remove (i), To tableau_B.count, s'il était à 10 éléments par exemple, passe à 9. Ok? Or tu continue dans la boucle k à dire : Si tableau_B0(k) = tableau_B(i). Si i était égal à tableau_B.count initial, soit 10, tableau_B(10) n'existant plus, tu va beugguuer.....

    Dim tableau_B As New Collection
    Dim tableau_B0 As New Collection
    Dim Tabl() As Integer
    Dim i As Integer, k As Integer, Cpt As Integer
    
    For i = tableau_B.Count To 1 Step -1
        For k = tableau_B0.Count To 1 Step -1
            If tableau_B0(k) = tableau_B(i) Then
                ReDim Preserve Tabl(Cpt)
                Tabl(Cpt) = i
                Cpt = Cpt + 1
                tableau_B0.Remove k
            End If
        Next k
    Next i
    For i = 0 To UBound(Tabl)
        tableau_B.Remove Tabl(i)
    Next

    1
    1. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      Bonjour
      pijaku

      Si tu instancies par New collection, il faut fermer par
      set lacollection=nothing
      sinon tu risques de garder en mémoire les item de la collection (expérience perso)

      mais il vaut mieux utiliser les dictionary
      (pas le temps d'écrire le code)
      2 dico
      creer la liste des keys de dico1
      liste=dico1.keys
      parcourir liste en testant dico2 par if exists
      si oui, tu supprimes la key testée des 2 dicos

      ala fin tu fais 2 liste.keys que ttu colles à l'endroit voulu
      0
    2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      Salut michel,
      Merci de l'info. Ca ils le disent pas sur boisgontierjacques.free.fr...
      Très bon à savoir.
      Merci
      A+
      0
    3. michel_m Messages postés 18903 Date d'inscription   Statut Contributeur Dernière intervention   3 320
       
      j'ai un topo la dessus (sur New) je le chercherai dans mon B....
      0
    4. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      Ok.
      J'ai lu.
      Très bon topo, explicite, j'ai tout compris, du moins je le crois...
      Du coup, faut que je change partout mes :
      Dim Collec As New Collection

      Par :
      Dim Collec As Collection
      Set Collec = New Collection

      Ou par :
      Dim Collec As New Collection
      'blabla
      Set Collec = Nothing

      Merci du tuyau
      0
  2. leen.net Messages postés 247 Statut Membre 13
     
    je pense que tu compares chaque cellule de B par B0,
    c.a.d que si B[1]==B0[4], il ne les supprime pas... c'est ça ce que tu voudrais??
    0
    1. mrsmith1
       
      en fait je voudrais qu'il supprime les éléments communs des 2 listes
      0
  3. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
     
    Bon...
    Ou as tu été chercher la syntaxe RemoveAt???
    La bonne syntaxe pour supprimer un élément d'une collection est :
    Variable.Remove item:=index
    Soit dans ton cas : tableau_B.Remove i

    Mais quel est l'intérêt de boucler sur tes collections si tu souhaites juste éviter les doublons? L'intérêt d'une collection est justement de créer des listes sans doublons.

    Et si avant de te lancer tête baissée dans des macros que tu ne maîtrise pas, tu te renseignait un minimum. Ou alors si tu nous disais exactement :
    - ce que tu as au départ
    - ce que tu veux en faire...
    0
    1. mrsmith1
       
      j'avais trouvé :
      C- Éliminer, insérer un élément dans une collection.

      L.Remove("toto") 'On enlève un élément de la liste

      L.RemoveAt(0) 'On enlève l'élément 0 de la liste

      Insert permet d'insérer à un index spécifié.

      L.Insert( position, Ainserrer)

      Du coup, ce que je cherche a faire est de prendre une feuille excel B, après j'en tire une liste qui peut avoir des doublons, je dois supprimer les doublons et je doit extraire le nombre d'elements de la liste.
      Ensuite, je fais la meme chose avec la feuille excel B0.

      A partir de la, jai 2 collections (B et B0), et je souhaite, dans les 2 collections, supprimer les éléments communs.
      0
    2. pijaku Messages postés 13513 Date d'inscription   Statut Modérateur Dernière intervention   2 773
       
      Pour remplir une collection sans doublon, il te faut utiliser le paramètre Key.
      Exemple :
      Avec l'option Key, on peut interdire les doublons dans une collection. Et Remove pour supprimer :
      Sub CollectionSansDoublons()
        Dim MaListe As New Collection 
        On Error Resume Next
        MaListe.Add Item:="Dupont", key:="Dupont"
        MaListe.Add Item:="Durand", key:="Durand"
        MaListe.Add Item:="Martin", key:="Martin"
        MaListe.Add Item:="Martin", key:="Martin"
        MaListe.Remove 2
        For i = 1 To MaListe.count
          Cells(i, 5) = MaListe(i)
        Next i
      End Sub

      En clair, l'ajour d'un élément possédant le même Item ne fait rien. Si par contre le même paramètre Key apparait plusieurs fois, ton code Buggue : Erreur d'exécution 457 cette clé est déjà associée à un élément de la collection. En ajoutant donc On error resume next, cet élément n'est pas enregistré dans la collection et donc =====> Pas de doublons!

      Source : http://boisgontierjacques.free.fr/pages_site/Collection.htm
      Sources pour l'explication : Michel_m
      0