Inversion d'un tableau via dictionnaire VBA (pas de PQuery ou tcd)

Re BsAlv ,

C'est depuis 2003 que cette fonction existe...

image

re, vous pouvez encore me corriger ...

j'avais trouvé ceci, mais apparament, la liste n'était pas complète.

Bien pour savoir que cela existait déjà dans les versions <365 ...

Merci en tout cas !

image

Bonjour BsLav,

Je me fiais aussi à ce que Microsoft écrivait dans ses articles. J'ai découvert qu'il ne fallait pas le faire. Microsoft a oublié qu'un jour -once upon a time...- il avait pondu Excel 2003 (et les versions précédentes) et il ne les mentionne plus nulle part. La version 2003 était une excellente version. Je crois même que MS évite maintenant de citer les versions 2010 et 2013.

Bon, il est vrai que je suis un dinosaure rescapé de Multiplan et d'Excel IV et que la multitude des utilisateurs d'aujourd'hui ne sait même pas ce que sont que ces vieux machins. Il faut être paléontologue de l'informatique pour le savoir. A ce propos, je me suis aperçu avec surprise que parmi les gens des dernières générations baignées dans le numérique, certains avaient du mal à lire l'heure sur un cadran à aiguilles (*). Comme quoi le temps passe...

(*) à ce propos, voir ici.

Bonjour et merci à tous , vraiment pour vos solutions diverses et pertinentes !

@cousinhub Je vais regarder à ça mais pour le premier essai, je n'ai pas réussi à faire toutes les étapes

@tomato: beau code mais il me paraît trop complexe pour mes petites connaissances

And the winner is.... mafraise pour ses 2 solutions

Et moi aussi, j'ai connu Visicalc/Magicalc/Mutltiplan sur Mac) /Lotus123/Quattro/Excel en 1980-81...mais je n'ai pas suffisamment évolué même si je reste encore ébahi par ce programme magnifique.

Salut Patrick,
Salut les as,

comme le dit si bien Mafraise, rien de tel que du bon vieux VBA paléontologique pour mener à bien ce petit boulot!
Après ma pause estivale, ayant plus tâté du pourcentage en gravel qu'en Excel, j'ai déjà quasi tout oublié de la Bête immonde qu'est le Dico!

Un double-clic sur la feuille pour faire le taf!

For x = 2 To UBound(tTab1, 1)
    If tTab1(x, 2) <> sAgt Then _
        iIdx = iIdx + IIf(iIdx = 0, 2, 1): _
        ReDim Preserve tTab2(UBound(tTab1, 2), iIdx): _
        sAgt = tTab1(x, 2): _
        tTab2(0, iIdx - 1) = sAgt
   For y = 3 To UBound(tTab1, 2)
        If iIdx = 2 Then tTab2(y - 1, 0) = tTab1(1, y)
        tTab2(1, iIdx - 1) = tTab2(1, iIdx - 1) + tTab1(x, y)
        tTab2(y - 1, iIdx - 1) = tTab2(y - 1, iIdx - 1) + tTab1(x, y)
    Next
Next
10patrick.xlsm (22.18 Ko)

A+

Bonjour à tous

Oui Consolider est très ancien (même avant 2002) mais très limité à l'usage (j'avais renoncé à l'enseigner).

A la main l'adresse du classeur est inutile, la plage suffit.

Je partage l'avis de cousinhub : PowerQuery est bien plus simple pour ce type de manip. Si on ne maîtrise pas les subtilités de cousinhub on le fait à la souris en 4 étapes...

For x = 2 To UBound(tTab1, 1)
    If tTab1(x, 2) <> sAgt Then _
        iIdx = iIdx + IIf(iIdx = 0, 2, 1): _
        ReDim Preserve tTab2(UBound(tTab1, 2), iIdx): _
        sAgt = tTab1(x, 2): _
        tTab2(0, iIdx - 1) = sAgt
   For y = 3 To UBound(tTab1, 2)
        If iIdx = 2 Then tTab2(y - 1, 0) = tTab1(1, y)
        tTab2(1, iIdx - 1) = tTab2(1, iIdx - 1) + tTab1(x, y)
        tTab2(y - 1, iIdx - 1) = tTab2(y - 1, iIdx - 1) + tTab1(x, y)
    Next
Next

Très admiratif de la rapidité et de la brièveté du code !!! Chapeau !

Hello,

...

@cousinhub Je vais regarder à ça mais pour le premier essai, je n'ai pas réussi à faire toutes les étapes

...

Je te propose de tout faire à la main :

J'ai sélectionné la cellule A5 (début de ton tableau "Tableau1", puis dans le ruban "Données", j'ai cliqué sur "A partir de Tableau ou d'une Plage"

image

L'éditeur PQ s'est ouvert automatiquement, et il y a une conversion automatique des données selon leur type

En rouge (à droite), tu as les étapes, et en vert (à gauche), tu peux développer pour voir le nom de la requête (qui porte le même nom que ton Tableau)

image

Tu sélectionnes la 1ère colonne (Jour par Tâche) en cliquant sur le titre de la colonne, puis clic droit, "Supprimer"

image

La colonne "Noms" devient alors la 1ère colonne (et est sélectionnée automatiquement). Un clic droit sur le titre, et tu sélectionnes "Dépivoter les autres colonnes"

image

Toutes tes colonnes se mettent alors en ligne (TA1, ligne 1, TA2, ligne 2....) dans la colonne "Attribut", et leur valeur correspondante dans la colonne "Valeur"

image

On va maintenant faire l'inverse, à savoir pivoter la colonne des Noms.

Tu sélectionnes la colonne "Noms", et dans le ruban "Transformer", tu cliques sur "Pivoter la colonne"

image

Et dans la boîte de dialogue qui s'ouvre, tu lui détermine l'opération à effectuer.

Tu déplies le menu "Colonne de valeurs", tu choisis la colonne "Valeur", puis tu déplies le menu "Options avancées", et normalement, PQ va te proposer par défaut "Somme"

image image

Les calculs se font tout seul, il te reste juste à charger le résultat où tu le désires, en cliquant sur "Fermer et charger/Fermer et charger dans...", et tu te laisses guider. A savoir, tu peux modifier le nom générique "Attribut" en double-cliquant dessus, et en mettant "Tâches", par exemple.

image

Et voilà, tu as ton résultat, sans jamais avoir codé...

Magique, non?

Bon courage

Bonjour Curulis,

J'ai souvent remarqué que la méthode par tableau trié est la plus rapide, même plus véloce que les méthodes utilisant les dictionary. En effet, on évite les accès incessants aux structures tierces que sont les dictionary. En plus les dictionary ne sont pas natifs sous OS Apple.

Cependant dans le cas général, il faut absolument que le tableau soit trié horizontalement (ici selon le nom).

Il faudra donc rajouter 3 ou 4 lignes pour s'en assurer: 1) lire le tableau source initial ti - 2) trier selon les noms - 3)lire le tableau source trié t - 4) re-balancer le tableau initial ti sur la feuille. Comme le tri des lignes est très rapide sous Excel, ça ne pénalise pas la méthode.

En fait presque nous tous dans ce fil n'avons peu ou pas respecté la volonté de patrick1957 qui désirait s'entrainer sur les dictionary. 'Sortir de la grotte' nous fait un peu de bien à nous les répondeurs, non?

Bonjour patrick1957,

Les logiciels que tu as cités démontrent que, tout comme moi, tu es aussi un vieux dinosaure de la même génération que ma pomme .

Salut Mafraise,

j'ai commencé par vouloir trier le tableau...

Range("A5").CurrentRegion.Sort key1:=Range("B6"), order1:=xlAscending, Orientation:=xlTopToBottom, Header:=xlYes

mais ça m'a foutu un beau bazar!

image

Jai donc coupé au plus court!
Et comme, manifestement, je suis de la même génération aussi, je suis resté au chaud dans ma grotte, le Dico et moi n'étant pas en bons termes!

A+

Re Curulis,

Curulis a dit : j'ai commencé par vouloir trier le tableau...

Range("A5").CurrentRegion.Sort key1:=Range("B6"), order1:=xlAscending, Orientation:=xlTopToBottom, Header:=xlYes

mais ça m'a foutu un beau bazar!

En fait, il y a des reliquats bizarres dans ses données sources de départ. Si on copie les données et qu'on les recolle dessus en valeur alors tout s'arrange.

...

Curulis a dit : Et comme, manifestement, je suis de la même génération aussi, je suis resté au chaud dans ma grotte, le Dico et moi n'étant pas en bons termes!

...


Hello everybody, et surtout patrick1957...

J'espère que mon petit tuto, qui m'a quand même pris quelque trois quart d'heure et demi, voire plus, aura servi à quelque chose, surtout à ton mantra....

Signature....

Mais..je continue à apprendre à 68 ans ( en 2025) et j'aime ça :)

Hope....

Bonne soirée, et bon dimanche

RE

"Mais..je continue à apprendre à 68 ans"

J'ai formé des personnes de 14 à 87 ans donc tu as encore 20 ans pour apprendre !

Hello,

Super ton tuto cousinhub

Je me sens un peu isolé pour avoir suivi les consignes patrick1957 ne sois pas affolé par mon code. Au delà de ta demande, j'ai étoffé avec un microsystème clé en main, mais le coeur de la machine c'est le point suivant qui crée 3 dictionnaires (nomUniques, tachesUniques et avec dict : la somme associée au couple nom/tache)

' === 4. Lecture et agrégation ===

Travailler avec un tableau structuré en source est une méthode très recommandable permettant d'éviter les externalités négatives que pourraient rencontrer certains des autres codes proposés précédemment. Notamment si l'utilisateur change la structure de sa source. L'utilisateur est d'ailleurs la source principale d'un éventuel bazar dans l'évolution et la maintenance d'un tableur

Eviter de coder "en dur" est aussi, autant que faire se peut, à privilégier. A défaut, toute évolution en sera freinée ou empêchée.

Si vous vous intéressez aux dictionnaires, voici un petit tuto :

1 - Principe de base
Un dictionnaire est une structure qui stocke des paires clé/valeur :

Key = identifiant unique

Item = donnée associée à la clé

2 - Déclaration et créatio

Dim d As Object
Set d = CreateObject("Scripting.Dictionary")

3 - Méthodes et propriétés principales

.Add key, item → ajoute une paire clé/valeur
.Item(key) → accède ou modifie une valeur
.Exists(key) → vérifie si la clé existe
.Remove(key) → supprime une clé
.RemoveAll → vide le dictionnaire
.Count → nombre d’éléments
.Keys → renvoie un tableau de toutes les clés
.Items → renvoie un tableau de toutes les valeurs

4 - Exemple simple

Sub ExempleDico()
Dim d As Object
Set d = CreateObject("Scripting.Dictionary")

d.Add "Nom", "Dupont"
d.Add "Age", 35
d.Add "Ville", "Paris"

MsgBox d.Item("Ville") ' affiche Paris

Dim k As Variant
For Each k In d.Keys
Debug.Print k, d.Item(k)
Next k
End Sub

5 - Avantages

Accès rapide aux éléments via la clé

Pas besoin d’index numérique

Idéal pour les recherches, correspondances, regroupements

Structure dynamique (pas besoin de redimensionner)

6 - Inconvénients

Les éléments ne sont pas triés

Utilise un peu plus de mémoire qu’un tableau

Clés uniques obligatoires

Nécessite la référence "Microsoft Scripting Runtime" pour un typage fort

7 - Items complexes

a) Array en item
On peut stocker un tableau dans un item :

Dim arr(1 To 3)
arr(1) = "A": arr(2) = "B": arr(3) = "C"
d.Add "Lettres", arr
Debug.Print d("Lettres")(2) ' affiche B

b) Dictionnaire de dictionnaires
On peut aussi imbriquer des dictionnaires :

Dim dMain As Object, dSub As Object
Set dMain = CreateObject("Scripting.Dictionary")
Set dSub = CreateObject("Scripting.Dictionary")
dSub.Add "Nom", "Durand"
dSub.Add "Age", 40
dMain.Add "Client1", dSub
Debug.Print dMain("Client1")("Nom") ' affiche Durand

8 - Quand l’utilise

Recherche rapide de valeurs par clé

Correspondances (code → libellé)

Comptage, regroupement, suppression de doublons

Petites structures hiérarchiques (dico de dico)

Bye

Bonjour tomato,

Super Tomato ton petit tuto.

Mais il reste un point négatif à tout cela : le dictionary n'est pas disponible sur les systèmes Apple. Donc dès qu'on utilise un dictionary, on présuppose que tous les utilisateurs de la macro seront sous environnement Windows, ce qui n'est pas toujours le cas.

Il me semble que patricktoulon avait créé une classe afin "d'implanter'' un type dictionary pour les Excel sous Apple, type qui utilise la même syntaxe (et donc le code) que le type dictionary sous windows. Mais je n'ai pas testé puisque pas d'Apple.

re,

ma référence pour les dictionaires, c'est https://excelmacromastery.com/vba-dictionary/ (en anglais), mais tomato a déjà mentionné les plus importants.

Je ne le sais pas pour 100%, mais je pense que dans le future les dictionaires ne seront plus supportés par MO (future = quelque années), mais alors on utilisera l'outil de PatrickToulon ...

Bonjour BsAlv,

Sinon pour la documentation en français, il y a aussi le miroir de l'excellent site du très regretté J.Boisgontier qui nous a quitté et dont l'adresse est ICI. Son site reste une mine d'or.

Bonjour à tous !

tomato, dans ce cas :

image

arr peut-il être de type personnalisé ?

Type LouReeD
    O As Shape
    T As Double
    L As Double
End Type
Dim arr(1 to 5) As LouReeD
arr(2).T = 200
d.Add "Formes", arr
Debug.Print d("Formes")(2).T ' affiche la composante T du type LouReeD du deuxième élément du tableau arr

je n'ai pas testé, mais c'est ce dont j'avais pensé avoir besoin...

@ bientôt

LouReeD

Bon j'ai essayé et cela ne fonctionne pas... tout du moins je n'y arrive pas...

image

Cela se bloque à la ligne d.Add "Formes", arr avec arr surligné...

@ bientôt

LouReeD

Rechercher des sujets similaires à "inversion tableau via dictionnaire vba pas pquery tcd"