Aide Scripting.Dictionary

cathodique

XLDnaute Barbatruc
Bonjour la communauté,

Je sollicite votre aide. Je vous précise que mes connaissances en VBA sont des plus limités. J'ai donc récupéré, un code de Robert qui fonctionne bien. Il me permet de récupèrer des données d'une feuille source vers des feuilles de destination sans doublons (source colonne B vers Destination colonne A). Je voudrais compléter ce transfert comme ceci: source colonnes F et G vers Destination colonnes B et C. Je vous remercie d'avance. Avec les exemples de Boisgontier, j'ai bien compris la logique du code avec l'objet scripting.dictionary et suis parvenu à réaliser des formulaires avec bombobox, listbox et textbox en cascade. Par contre, là je nage vraiment.
Code:
Sub essai3()
Dim bd As Object '(onglet BD)
Dim dico As Object '(DICtiOnnaire)
Dim dl As Integer '(Dernière Ligne)
Dim pl As Range 'PLage)
Dim cel As Range '(CELlule)
Dim temp As Variant '(tableau TEMPoraire)
Dim i As Integer '(Incrément)
Dim dics As Object 'DICtionnaireS)
Dim o As Object '(Onglet)
Dim teo As Variant '(tableau TEmporaire Outils)
Dim x As Integer 'variable x
Dim y As Integer 'variable y
Dim dercol As Integer '(Dernière colonne)

Set bd = Sheets("Consultation") 'définit l'onglet bd
Set dico = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
dl = bd.Cells(Application.Rows.Count, 1).End(xlUp).Row 'dernière ligne éditée dl de la colonne 1 (=A) de l'onglet bd
Set pl = bd.Range("B8:B" & dl) 'définit la plage pl

For Each cel In pl 'boucle sur toutes les cellules cel de la plage pl
    dico(cel.Value) = "" 'alimente le dictionnaire dico
Next cel 'prochaine cellule de la boucle
temp = dico.keys 'récupère le dictionnaire sans doublon dans le tableau temp

For i = 0 To UBound(temp) 'boucle 1 : sur toutes les valeurs uniques du tableau temp
    Set o = Sheets(temp(i)) 'définit l'onglet o
    o.UsedRange.Clear 'efface les anciennes données
    o.UsedRange.MergeCells = False
    
    bd.Range("A1").AutoFilter 'lance le filtre automatique
    bd.Range("A1").AutoFilter field:=2, Criteria1:=temp(i) 'filtre automatique sur la colonne 2 (=B) avec la valeur   temp(i) comme critère

    Set dics = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dics
        For Each cel In pl.Offset(0, 2).SpecialCells(xlCellTypeVisible) 'boucle 2 : sur toutes les cellules visibles cel de la plage pl déclalée d'un colonne à droite
        dics(cel.Value) = "" 'alimente le dictionnaire dics
    Next cel 'prochaine cellule de la boucle 2
    
    o.Range("A8").Resize(dics.Count) = Application.Transpose(dics.keys) 'renvoie en colonne à partir de A2 la liste des outils sans doublons
     
    bd.Range("A1").AutoFilter 'annule le filtre automatique
Next i 'prochaine valeur de la boucle 1
End Sub

Je vous remercie beaucoup.
 

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Bonjour Robert,

Je te prie de me donner tes impressions aux petites modifications d'adaptation que j'ai effectué à ton code initial. je te rappelle que je suis débutant.
Puis-je par le même occasion te demander de me suggérer une solution pour le transfert des données restantes? Car la mise en page entre la feuille source et les feuilles de destination à changer. J'ai pensé à la fonction sommeProd dans une boucle.

Pour Sommeprod ça va, je pourrais m'en sortir, mais pour insérer dans le code la boucle, c'est une autre paire de manche.

Je te remercie par avance. Je joins une partie du fichier initial et te précise que les données de la feuille source ("Consultation") proviennent d'une BD en fonction de la date et de la valeur de la cellule ("I1"), donc le nombre de lignes est variable.

Et te remerciant beaucoup.

Cordialement,
Cathodique
 

Pièces jointes

  • Dictionary-Transfert.xls
    76.5 KB · Affichages: 52

Robert

XLDnaute Barbatruc
Repose en paix
Re : Aide Scripting.Dictionary

Bonjour Cathodique, bonjour le forum,

En fait je vois pas bien où tu veux en venir.
je te propose de mettre le même fichier avec (juste dans le premier onglet Stt) le résultat désiré... Ça nous permettra de comprendre ce que tu voudrais faire faire à la macro.
 

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Bonsoir tout le monde,

En amateur que je suis. Je suis trompé de fichier et de code. Pour me faire la main comme dit, j'ai manipulé les codes et fais des tests pour me faire une idée.

je revois tout ça et je joins un autre fichier (avec l'onglet Olc ou Gzc, qui recevront des données n'apparaissant su Stt).

Déjà, avec cette macro, de la feuille source, je constitue les entête de ligne et de colonne des tableaux qui recevront les données contenues dans celle-ci.

Toutes mes excuses, pour mon cafouillage.

Bonne soirée!
 

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Rebonsoir,

En réalité je ne m'étais pas trompé de fichier, juste une modification mineure que j'ai apporté (suppression d'une colonne).
Voilà, j'ai rajouté une feuille représentant le résultat désiré pour l'onglet Olc, j'espère avoir bien exposer mon problème.

Merci beaucoup.
 

Pièces jointes

  • Dictionary-Transfert-Bis.xls
    122 KB · Affichages: 74

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Bonjour Robert, bonjour tout le monde,

Je sollicite votre aide pour comprendre le mécanisme de fonctionnement d'un dictionnaire. Une doc ou lien ne seront pas de refus. Sur je fichier joint j'y ai mis le résultat final.
Sur filtrage en colonne B, on transfère toutes les données de la colonne D en colonne A sur les feuilles de destination. Je voudrais faire la même chose pour les colonnes F et G, les données se mettront respectivement en colonnes B et D.

exemple:
feuille source: filtre sur Stt en colonne B
col B--------------colD----------colF---------colG
Stt --------------T1A----------64,4---------45,5
etc...

Feuille destination:
colA-------------colB-----------colC
T1A-------------64,4-----------45,5
etc...

Ne voulant pas abuser, je sollicite votre aide pour cette partie. Le reste du travail se sera dans le cadre d'une autre discussion, si je ne trouve pas de solution. Mon idée est de compter le nombre d'éléments que contient le dictionnaire et faire une boucle sur la formule sommeprod. enfin, ça c'est une autre paire de manche. Pour le moment, je voudrai surtout comprendre comment fonctionne le dictionnaire.

Merci beaucoup.
 

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Bonjour Pierrot93,

Je te remercie pour ton lien, je connais bien ce site mais vu mon niveau je n'ai pas bien saisi pour utiliser le dictionnaire sur une feuille Excel. Alors que, me basant sur les exemples de Boisgontier, je suis parvenu à l'utiliser pour faire des formulaires de selection de données en cascades (combinant Combobox, Listbox et textbox). J'avais bien saisi le truc mais là, je sèche.

Merci beaucoup. très bonne journée!
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Aide Scripting.Dictionary

Bonjour le fil, bonjour le forum,

Voici une nouvelle proposition avec le code ci-dessous. Je te laisse faire pour la mise en forme et les formules...
Le code :
Code:
Sub essai()
Dim bd As Object '(onglet BD)
Dim dl As Integer '(Dernière Ligne)
Dim pl As Range 'PLage)
Dim dicB As Object '(DICtiOnnaire de la colonne B)
Dim cel As Range '(CELlule)
Dim teB As Variant '(tableau TEMPoraire)
Dim i As Integer '(Incrément)
Dim o As Object '(Onglet)
Dim dicC As Object '(DICtiOnnaire de la colonne C)
Dim teC As Variant '(tableau TEMPoraire)
Dim dicD As Object '(DICtiOnnaire de la colonne D)
Dim teD As Variant '(tableau TEMPoraire)
Dim y As Integer 'variable y
Dim x As Integer 'variable x
Dim dercol As Integer '(Dernière colonne)

Application.ScreenUpdating = False 'masque les changements à l'écran
Set bd = Sheets("Consultation") 'définit l'onglet bd
dl = bd.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée dl de la colonne 1 (=A) de l'onglet bd
Set pl = bd.Range("B8:B" & dl) 'définit la plage pl
Set dicB = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dicB (colonne B)
For Each cel In pl 'boucle sur toutes les cellules cel de la plage pl
    dicB(cel.Value) = "" 'alimente le dictionnaire dicB
Next cel 'prochaine cellule de la boucle
teB = dicB.keys 'récupère le dictionnaire sans doublon dans le tableau teB
For i = 0 To UBound(teB) 'boucle 1 : sur toutes les valeurs uniques du tableau teB
    Set o = Sheets(teB(i)) 'définit l'onglet o
    o.UsedRange.Clear 'efface les anciennes données
    o.UsedRange.MergeCells = False 'défusionnes les cellulues fusionnées
    bd.Range("A7").AutoFilter 'lance le filtre automatique
    bd.Range("A7").AutoFilter field:=2, Criteria1:=teB(i) 'filtre automatique sur la colonne 2 (=B) avec la valeur teB(i) comme critère
    Set dicC = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dicC
    'boucle 2 : sur toutes les cellules visibles cel de la plage pl déclalée d'un colonne à droite
    For Each cel In pl.Offset(0, 1).SpecialCells(xlCellTypeVisible)
        dicC(cel.Value) = "" 'alimente le dictionnaire dicC
    Next cel 'prochaine cellule de la boucle 2
    teC = dicC.keys 'définit le tabeau teC
    ''DEBUT ENTETE DU TABLEAU 1ERE PARTIE
    o.Range("A6") = "Localisation"
    o.Range("A7") = "Localisation"
    o.Range("B6") = "Alimentation"
    o.Range("C6") = "Alimentation"
    o.Range("B7") = "Tension" & Chr(10) & "(Volt)"
    o.Range("C7") = "Courant" & Chr(10) & "(Ampère)"
    y = 4 'initialise la variable y
    For x = 0 To UBound(teC) 'boucle 3 : sur toutes les valeurs uniques du tableau teC
        o.Cells(6, y).Value = teC(x) 'place l'outil dans le tableau
        o.Cells(6, y).Offset(, 1).Value = teC(x) 'place l'outil dans le tableau
        o.Cells(7, y).Value = "Potentiel" & Chr(10) & "(mV)"
        o.Cells(7, y).Offset(, 1).Value = "Courant" & Chr(10) & "(mA)"
        y = y + 2 'incrément y
    Next x 'prochain outil de la boucle 3
     ''FIN entete ligne DU TABLEAU'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    dercol = o.Range("A6").End(xlToRight).Column
    o.Cells(6, dercol + 1).Value = "Direction"
    o.Cells(6, dercol + 1).Offset(, 1).Value = "Observations"
    o.Cells(7, dercol + 1).Value = "Direction"
    o.Cells(7, dercol + 1).Offset(, 1).Value = "Observations"
    o.Range("J2").Value = o.Name 'place le nom de l'onglet en J2
    Set dicD = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dicC
    'boucle 3 : sur toutes les cellules visibles cel de la plage pl déclalée de deux colonnes à droite
    For Each cel In pl.Offset(0, 2).SpecialCells(xlCellTypeVisible)
        dicD(cel.Value) = "" 'alimente le dictionnaire dicC
    Next cel 'prochaine cellule de la boucle 3
    teD = dicD.keys 'définit le tabeau teD
    For x = 0 To UBound(teD) 'boucle 4 : sur toutes les valeurs uniques du tableau teD
        bd.Range("A7").AutoFilter field:=4, Criteria1:=teD(x) 'filtre la colonne D par rapport à la valeur unique
        'copie la cellule en colonne D de la première ligne filtrée et la colle dans la colonne A de l'onglet o
        pl.SpecialCells(xlCellTypeVisible).Offset(0, 2).Cells(1).Copy o.Cells(Application.Rows.Count, 1).End(xlUp).Offset(1, 0)
        'copie la cellule en colonne F de la première ligne filtrée et la colle dans la colonne B de l'onglet o
        pl.SpecialCells(xlCellTypeVisible).Offset(0, 4).Cells(1).Copy o.Cells(Application.Rows.Count, 2).End(xlUp).Offset(1, 0)
        'copie la cellule en colonne G de la première ligne filtrée et la colle dans la colonne CA de l'onglet o
        pl.SpecialCells(xlCellTypeVisible).Offset(0, 5).Cells(1).Copy o.Cells(Application.Rows.Count, 3).End(xlUp).Offset(1, 0)
        bd.Range("A7").AutoFilter field:=4 'supprime le filtre en colonne D
    Next x 'prochaine valeur de la boucle 4
Next i 'prochaine valeur de la boucle 1
bd.Range("A7").AutoFilter
Application.ScreenUpdating = True 'affiche les changements à l'écran
MsgBox "Fait ! "
End Sub
 

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Bonjour Robert, Bonjour le fil,

Toute ma gratitude Robert. Ton code est parfait.
J'ai passé des nuits blanches sur ce problème. J'ai fait beaucoup de recherches pour maitriser cet outil.

Hélas, mes connaissances en VBA sont très limités. Puis-je te demander, s'il aurait été possible de récupérer les données de colonnes B, F et G dans un tableau avec le dictionnaire et les transférés comme avec le précédant code: "o.Range("A8").Resize(dics.Count) = Application.Transpose(dics.keys)"
en ajoutant 2 lignes de code du genre: o.Range("A8").Resize(dics.Count) = Application.Transpose(dics.items)

C'est juste pour savoir et me creuser les méninges pour me perfectionner. Je te remercie beaucoup.

Cordialement,

Cathodique
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Aide Scripting.Dictionary

Bonjour le fil, bonjour le forum,

Je pensais ne pas y parvenir c'est pourquoi je t'avais proposé une autre méthode... Finalement j'ai réussi, je pense, avec cette partie :
Code:
    tco = Array(2, 4, 5) 'définit le tableau des colonnes Origine
    tcc = Array(1, 2, 3) 'définit le tableau des colonnes Cible
    For x = 0 To 2 'boucle sur les 3 éléments d'un des tableaux
        Set dics = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dics
        'boucle 2 : sur toutes les cellules visibles cel de la plage pl déclalée de tco(x) colonnes à droite
        For Each cel In pl.Offset(0, tco(x)).SpecialCells(xlCellTypeVisible)
            dics(cel.Value) = "" 'alimente le tableau
        Next cel 'prochaine cellule de la boucle 2
        'renvoie en colonne tcc(x) à partir de la ligne 8 la liste des outils sans doublons
        o.Cells(8, tcc(x)).Resize(dics.Count) = Application.Transpose(dics.keys)
    Next x

Le code en entier :
Code:
Sub essai2()
Dim bd As Object '(onglet BD)
Dim dl As Integer '(Dernière Ligne)
Dim pl As Range 'PLage)
Dim dico As Object '(DICtiOnnaire)
Dim cel As Range '(CELlule)
Dim temp As Variant '(tableau TEMPoraire)
Dim i As Integer '(Incrément)
Dim o As Object '(Onglet)
Dim dics As Object 'DICtionnaireS)
Dim teo As Variant '(tableau TEmporaire Outils)
Dim y As Integer 'variable y
Dim x As Integer 'variable x
Dim dercol As Integer '(Dernière colonne)
Dim tco As Variant 'déclare la variable tco (Tableau des Colonnes Origine)
Dim tcc As Variant 'déclare la variable tcc (Tableau des Colonnes Cible)

''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
Set bd = Sheets("Consultation") 'définit l'onglet bd
dl = bd.Cells(Application.Rows.Count, 1).End(xlUp).Row 'définit la dernière ligne éditée dl de la colonne 1 (=A) de l'onglet bd
Set pl = bd.Range("B8:B" & dl) 'définit la plage pl
Set dico = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dico
For Each cel In pl 'boucle sur toutes les cellules cel de la plage pl
    dico(cel.Value) = "" 'alimente le dictionnaire dico
Next cel 'prochaine cellule de la boucle
temp = dico.keys 'récupère le dictionnaire sans doublon dans le tableau temp
For i = 0 To UBound(temp) 'boucle 1 : sur toutes les valeurs uniques du tableau temp
    Set o = Sheets(temp(i)) 'définit l'onglet o
    o.UsedRange.Clear 'efface les anciennes données
    o.UsedRange.MergeCells = False
    bd.Range("A1").AutoFilter 'lance le filtre automatique
    bd.Range("A1").AutoFilter field:=2, Criteria1:=temp(i) 'filtre automatique sur la colonne 2 (=B) avec la valeur temp(i) comme critère
    '''ENTETE LIGNE (6) DU TABLEAU'''
    Set dics = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dics
    For Each cel In pl.Offset(0, 1).SpecialCells(xlCellTypeVisible) 'boucle 2 : sur toutes les cellules visibles cel de la plage pl déclalée d'un colonne à droite
        dics(cel.Value) = "" 'alimente le dictionnaire dics
    Next cel 'prochaine cellule de la boucle 2
    teo = dics.keys 'définit le tabeau teo
    ''DEBUT ENTETE DU TABLEAU 1ERE PARTIE
    o.Range("A6") = "Localisation"
    o.Range("A7") = "Localisation"
    o.Range("B6") = "Alimentation"
    o.Range("C6") = "Alimentation"
    o.Range("B7") = "Tension" & Chr(10) & "(Volt)"
    o.Range("C7") = "Courant" & Chr(10) & "(Ampère)"
    ''SUITE TABLEAU EXTRAITE DE LA BD''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    y = 4 'initialise la variable y
    For x = 0 To UBound(teo) 'boucle 3 : sur toutes les outils (sans doublon)
        o.Cells(6, y).Value = teo(x) 'place l'outil dans le tableau
        o.Cells(6, y).Offset(, 1).Value = teo(x) 'place l'outil dans le tableau
        o.Cells(7, y).Value = "Potentiel" & Chr(10) & "(mV)"
        o.Cells(7, y).Offset(, 1).Value = "Courant" & Chr(10) & "(mA)"
    y = y + 2 'incrément y
    Next x 'prochain outil de la boucle 3
     ''FIN entete ligne DU TABLEAU'''''''''''''''''''''''''''''''''''''''''''''''''''''''''
     dercol = o.Range("A6").End(xlToRight).Column
     o.Cells(6, dercol + 1).Value = "Direction"
     o.Cells(6, dercol + 1).Offset(, 1).Value = "Observations"
     o.Cells(7, dercol + 1).Value = "Direction"
     o.Cells(7, dercol + 1).Offset(, 1).Value = "Observations"
    '''ENTETE COLONNE (A) DU TABLEAU'''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
    tco = Array(2, 4, 5) 'définit le tableau des colonnes Origine
    tcc = Array(1, 2, 3) 'définit le tableau des colonnes Cible
    For x = 0 To 2 'boucle sur les 3 éléments d'un des tableaux
        Set dics = CreateObject("Scripting.Dictionary") 'définit le dictionnaire dics
        'boucle 2 : sur toutes les cellules visibles cel de la plage pl déclalée de tco(x) colonnes à droite
        For Each cel In pl.Offset(0, tco(x)).SpecialCells(xlCellTypeVisible)
            dics(cel.Value) = "" 'alimente le tableau
        Next cel 'prochaine cellule de la boucle 2
        'renvoie en colonne tcc(x) à partir de la ligne 8 la liste des outils sans doublons
        o.Cells(8, tcc(x)).Resize(dics.Count) = Application.Transpose(dics.keys)
    Next x
    bd.Range("A1").AutoFilter 'annule le filtre automatique
Next i 'prochaine valeur de la boucle 1
End Sub
 

cathodique

XLDnaute Barbatruc
Re : Aide Scripting.Dictionary

Bonsoir Robert, Bonsoir Le Forum

Il n'y a pas à dire, tu es vraiment fort, très fort même. Ton dernier est plus rapide que le précédent.
Je te remercie beaucoup. maintenant, je dois m'atteler pour trouver la solution pour insérer les formules.

Toute ma gratitude.
 

Robert

XLDnaute Barbatruc
Repose en paix
Re : Aide Scripting.Dictionary

Bonsoir le fi, bonsoir le forum,

Bonsoir Robert, Bonsoir Le Forum
Il n'y a pas à dire, tu es vraiment fort, très fort même

Non mais ça va pas non ! Faut pas dire des choses comme ça Cathodique, je suis capable de les croire et après je prends tellement du melon que j'ose même plus passer par Cavaillon...
 

Membres actuellement en ligne

Statistiques des forums

Discussions
314 636
Messages
2 111 463
Membres
111 151
dernier inscrit
KARIMTAPSO