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 :

Utilisation d'un dictionnaire pour fusionner 2 tableaux, adaptation du code


Sujet :

Macros et VBA Excel

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Expert confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Juillet 2014
    Messages
    2 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 2 684
    Par défaut Utilisation d'un dictionnaire pour fusionner 2 tableaux, adaptation du code
    Bonjour,

    J'ai trouver un code sur ce site http://boisgontierjacques.free.fr/pa...re.htm#MergeMZ qui permet de fusioner deux tableaux en utilisant un dictionnaire, je travaille sur l'adaptation de ce code pour résoudre mon problème et j'aurais bien besoin d'un coup de main.
    L'exemple qui va avec ce code contient deux tableaux simple avec une colonne ID et une colonne VALEUR.
    J'ai déjà réussi a adapter pour avoir plusieurs colonnes valeurs différentes et avoir plus que deux tableaux.
    Le dernier problème qu'il me reste c'est pour la colonne contenant l'identifiant, j'aurais aimé utilisé plusieurs cellules pour identifier un element,pour l'instant je concactène toute mes colonnes et je fais l'opération inverse une fois la fusion finie, mais j'aurais aimé savoir si il était possible de se passer de cette étape.
    Voici le code en question:
    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
    Sub fusion()
       Set d1 = CreateObject("Scripting.Dictionary")
       Set f1 = Sheets("ca2014")
       a = f1.Range("A2:B" & f1.[a65000].End(xlUp).Row)
       Set f2 = Sheets("ca2015")
       b = f2.Range("A2:B" & f2.[a65000].End(xlUp).Row)
       n = UBound(a) + UBound(b)
       Dim c: ReDim c(1 To n, 1 To 3)
       m = 0
       For i = LBound(a) To UBound(a)
         If Not d1.exists(a(i, 1)) Then m = m + 1: d1(a(i, 1)) = m: p = m Else p = d1(a(i, 1))
         c(p, 1) = a(i, 1): c(p, 2) = a(i, 2)
       Next i
       For i = LBound(b) To UBound(b)
         If Not d1.exists(b(i, 1)) Then m = m + 1: d1(b(i, 1)) = m: p = m Else p = d1(b(i, 1))
         c(p, 1) = b(i, 1): c(p, 3) = b(i, 2)
       Next i
       Sheets("fusion").[A2].Resize(d1.Count, UBound(c, 2)) = c
     End Sub
    Mon problème se situe je pense au niveau du If Not d1.exists(a(i, 1)) que j'aimerais adapter pour prendre plusieurs cellules.

    J'espère avoir été assez clair, merci d'avance à ceux qui essayeront de m'aider.

  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,

    peux-tu préciser l'agencement de tes données ?

    tu as combien de colonnes ? Combien (et quelles) colonnes constitueraient la clé ?

    il faudra additionner chaque paire de colonnes ne constituant pas la clé ?


    EDIT : en reprenant des tableaux de deux colonnes .... sans passer par un tableau et des indices intermédiaires lors du traitement

    exemple avec deux tableaux de 3 lignes et 2 colonnes (A1:B3 et E1:E3)
    affichage du résultat sur les colonnes H et I

    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
    Sub tableau()
    Dim A(), B()
    Dim C As Object
    Set C = CreateObject("Scripting.Dictionary")
     
    A = Cells(1, 1).Resize(3, 2).Value
    B = Cells(1, 5).Resize(3, 2).Value
     
    For i = LBound(A, 1) To UBound(A, 1)
        If Not C.exists(A(i, 1)) Then C.Add A(i, 1), A(i, 2) Else C(A(i, 1)) = C(A(i, 1)) + A(i, 2)
    Next i
     
    For i = LBound(B, 1) To UBound(B, 1)
        If Not C.exists(B(i, 1)) Then C.Add B(i, 1), B(i, 2) Else C(B(i, 1)) = C(B(i, 1)) + B(i, 2)
    Next i
     
    Cells(1, 8).Resize(C.Count, 1).Value = Application.Transpose(C.keys)
    Cells(1, 9).Resize(C.Count, 1).Value = Application.Transpose(C.items)
     
    End Sub

    Et une variante en une seule boucle imbriquée : on stocke tous les tableaux dans un tableau qu'on parcourt

    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
    Sub tableauDansArray()
    Dim A(), B(), D()
    Dim C As Object
    Set C = CreateObject("Scripting.Dictionary")
     
    A = Cells(1, 1).Resize(3, 2).Value
    B = Cells(1, 5).Resize(3, 2).Value
    D = Array(A, B)
     
    For j = LBound(D) To UBound(D)
        For i = LBound(D(j), 1) To UBound(D(j), 1)
            If Not C.exists(D(j)(i, 1)) Then C.Add D(j)(i, 1), D(j)(i, 2) Else C(D(j)(i, 1)) = C(D(j)(i, 1)) + D(j)(i, 2)
        Next i
    Next j
     
    Cells(1, 8).Resize(C.Count, 1).Value = Application.Transpose(C.keys)
    Cells(1, 9).Resize(C.Count, 1).Value = Application.Transpose(C.items)
     
    End Sub
    La variante est facilement modifiable pour ne pas utiliser le tableau B : on fait une boucle sur chaque feuille contenant un tableau, on stocke dans A, on parcours le tableau pour alimenter le dictionnaire

  3. #3
    Expert confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Juillet 2014
    Messages
    2 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 2 684
    Par défaut
    tu as combien de colonnes ? Combien (et quelles) colonnes constitueraient la clé ?
    Pour mes données ça peut varier suivant le détail des données qu'on me fourni.(à priori pour l'instant ce serait entre 4 et 8).

    Mais pour l'exemple deux devraient suffire (colonnes A et B), je pense qui si on m'aide pour le faire avec deux colonnes je devraient pouvoir le faire pour plus.

    il faudra additionner chaque paire de colonnes ne constituant pas la clé ?
    Non c'est des colonnes distinctes (somme d'argents, nombre de dossier, texte ..)
    pour l'exemple une seule colonne de valeur C

    Donc on aurait en entrée deux tableaux avec deux colonnes (A et B) pour l'indentifiant et une (C) pour les données
    Et en sortie un tableau avec deux colonnes (A et B) pour l'indentifiant et deux (C et D) contenant les données

    En fait je doit reproduire un tableau de bord avec des données qui viennent de 4 bases différentes (et non je n'ai pas accès aux bases juste aux export excel), certains identifiant se retrouvent dans plusieurs export mais pas tous et il n'y pas d'export qui contient tous les identifiants, le meilleur moyen que j'ai trouvé pour aggréger le tout c'est ça, ça marche très bien et c'est super rapide mais j'ai juste le problème de l'identifiant sur plusieurs cellules (que j'aimerais contourner autrement que par concaténation).

    edit: je m'excuse j'ai oublié le plus important, merci pour ton aide

  4. #4
    Expert confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Juillet 2014
    Messages
    2 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 2 684
    Par défaut
    EDIT : en reprenant des tableaux de deux colonnes .... sans passer par un tableau et des indices intermédiaires lors du traitement

    exemple avec deux tableaux de 3 lignes et 2 colonnes (A1:B3 et E1:E3)
    affichage du résultat sur les colonnes H et I
    retour après test de tes macros:

    J'aimerais pourvoir utiliser plusieurs colonnes(2 pour l'instant) pour définir mon identifiant
    Pas de sommes des valeurs
    (mais ça c'est ma faute je n'ai pas répondu assez vite)
    Par contre il y a un problème d'écrasement de données, je m'explique:
    j'ai tester avec dans mon premier tableau id1 id2 id3 et dans le second id4 id1 id2 à la sortie je n'ai que id1 id2 id4, je pense que la ligne avec id4 a écrasé celle avec l'id3
    edit je viens en chageant l'ordre du second tableaux id1 id2 id4 il ne me sort plus que id1 id2

  5. #5
    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
    Je viens de refaire un test (macro "tableauDansArray()") avec comme jeu de données :

    tableau 1 :

    A 1
    B 2
    C 3
    tableau 2 :

    A 4
    C 5
    E 6
    tableau résultat :

    A 5
    B 2
    C 8
    E 6
    je n'ai pas d'écrasement de données, tu peux montrer le code que tu as utilisé ?


    Ensuite, j'ai peur de ne plus saisir exactement ce que tu souhaites ... peux-tu transmettre un fichier exemple avec 2 tableaux de départ et le tableau d'arrivé souhaité ?

  6. #6
    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
    Billets dans le blog
    8
    Par défaut heu
    Bonjour
    j'ai cru comprendre que les doublons devaient être considérer sur plusieurs cellules
    c'est a dire doublons sur colonne 1 et 2 sur les 2 plages si c'est le cas
    http://www.developpez.net/forums/d13...bles-tableaux/

    Ps j'avais fait ca pour ceux qui ont Excel 2003 et donc pas la fonction removeduplicate
    mes fichiers dans les contributions:
    mail avec CDO en vba et mail avec CDO en vbs dans un HTA
    survol des bouton dans userform
    prendre un cliché d'un range

    si ton problème est résolu n'oublie pas de pointer : : ça peut servir aux autres
    et n'oublie pas de voter

  7. #7
    Expert confirmé
    Homme Profil pro
    Responsable des études
    Inscrit en
    Juillet 2014
    Messages
    2 684
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aude (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Responsable des études
    Secteur : Santé

    Informations forums :
    Inscription : Juillet 2014
    Messages : 2 684
    Par défaut
    @joe.levrai
    j'ai utiliser ton code à la virgule près en déplaçant quelques lignes de mes données
    edit: je viens de réassayer et effectivement ça marche, alors que hier non... , mais ça ne change pas mon problème d'identifiant sur plusieurs lignes

    pour l'exemple:Nom : exemple.png
Affichages : 863
Taille : 6,5 Ko
    Désolé de ne pas être très clair

    @patricktoulon
    Merci pour le lien je vais aller voir, mais une chose me fait peur, tu parles de removeduplicate, et je ne veux rien supprimer au contraire
    edit: je viens d'aller voir, comme sur l'exemple que j'avais trouvé ton identifiant est sur une seule colonne et tu utilise
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    mondico.Exists(tablo(i, 1))
    Ce que j'aimerais faire c'est dans le "Exists" mettre une plage et pas un seul élément, mais je ne sais pas le faire.

    J'espère avoir été un peu plus clair.
    Et merci pour votre aide.

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

Discussions similaires

  1. Réponses: 1
    Dernier message: 14/01/2013, 14h16
  2. [PDO] Probleme avec Array_merge pour fusionner deux tableaux ayant meme cle
    Par mickeynad dans le forum PHP & Base de données
    Réponses: 6
    Dernier message: 10/05/2010, 19h24
  3. [MySQL] fusionner deux tableaux par une variable commune pour faire un tuple unique
    Par mickeynad dans le forum PHP & Base de données
    Réponses: 1
    Dernier message: 11/04/2010, 11h28
  4. Réponses: 13
    Dernier message: 20/01/2009, 13h08
  5. utilisation d'objets ADO pour CMS sur POSTGRESQL7.3.2
    Par turbok dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 10/10/2003, 10h29

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