[Google Sheets] Transformer un tableau en liste exploitable plus facilement

Bonjour,

Comment concilier ergonomie et efficacité ?

Il est plus facile de rentrer des données sous forme de tableau. Prenons l'exemple d'une équipe dont on tient à jour un tableau de "présence" avec ces codes

CP=congés payés, EF=événement de famille, F=formation, Mat=maternité, P=présence, RTT
LundiMardiMercrediJeudiVendredi
MattPPPPP
KarimCPCPCPPP
TimFFF
GaëlleMatMatMatMatMat
JoachimEFEFPPP
MarghePPPRTTRTT
JuliePPPPP

On conçoit que mettre ces données sur un tableau structuré est plus facile que de rentrer une liste (et évite les redondances ou indomptabilités s'il advenait que quelqu'un mette 2 codes pour le même jour et la même personne). Pourtant, si on veut accéder à ces données, faire des analyses, des statistiques, des cumuls, il serait plus intéressant de travailler sur une pseudo-base de données (qui est plutôt disons-le une liste).

NomJourPrésence
MattLundiP
MattMardiP
MattMercrediP
MattJeudiP
MattVendrediP
KarimLundiCP
KarimMardiCP
KarimMercrediCP
KarimJeudiP
KarimVendrediP
TimMercrediF
TimJeudiF
TimVendrediF
GaëlleLundiMat
GaëlleMardiMat
GaëlleMercrediMat
GaëlleJeudiMat
GaëlleVendrediMat
JoachimLundiEF
JoachimMardiEF
JoachimMercrediP
JoachimJeudiP
JoachimVendrediP
MargheLundiP
MargheMardiP
MargheMercrediP
MargheJeudiRTT
MargheVendrediRTT
JulieLundiP
JulieMardiP
JulieMercrediP
JulieJeudiP
JulieVendrediP

Les formules de Google Sheets permettent de passer de l'un à l'autre. Pour cela on utilisera les fonctions suivantes :

columns
flatten
mod
query
roundup
rows
sequence
transpose
vlookup

je donne la solution tout de suite, tab étant le nom du tableau, sachant je donnerai des explications ci-dessous (excellent moyen de découvrir ou revisiter ces fonctions)

=query({
arrayformula(vlookup(arrayformula(ROUNDDOWN(flatten(sequence(rows(tab);columns(tab);0;1))/columns(tab))*columns(tab)+1);{flatten(sequence(rows(tab);columns(tab);1;1))\flatten(tab)};2;0))\
arrayformula(vlookup(mod(flatten(sequence(rows(tab);columns(tab);0;1));columns(tab))+1;{flatten(sequence(rows(tab);columns(tab);1;1))\flatten(tab)};2;0))\
flatten(tab)
};"select * where Col1 is not null and Col2 is not null and Col3 is not null";0)

https://docs.google.com/spreadsheets/d/1CgPHVY_PHgS_DoX1ifkXWOyTrmr7ggcxMyU5udcODE4/copy

Je précise que l'on trouve des solutions comme celle de BenCollins https://www.benlcollins.com/spreadsheets/unpivot-in-google-sheets/. La démarche est en effet similaire mais le résultat auquel on parvient ici est un peu plus simple et plus souple de mise en place.

FLATTEN

Cette fonction permet de mettre en colonne la plage de données, la prise en compte des cellules est la même que la lecture latine : de gauche à droite et de haut en bas en dessinant un Z

=flatten(tab)

On aura donc le résultat suivant de la plage citée plus haut

Lundi
Mardi
Mercredi
Jeudi
Vendredi
Matt
P
P
P
P
P
Karim
CP
CP
CP
P
P
Tim
F
F
F
Gaëlle
Mat
Mat
Mat
Mat
Mat
Joachim
EF
EF
P
P
P
Marghe
P
P
P
RTT
RTT
Julie
P
P
P
P
P

on a tous les éléments de la 3ème colonne (Valeurs), y compris la première cellule vierge en haut à gauche, et un peu plus ... on verra plus tard comment les cellules Noms et Jours seront supprimées.

SEQUENCE

sequence est une fonction qui permet de remplir un tableau de valeurs

=SEQUENCE(lignes; colonnes; début; pas)

le nombre de lignes du tableau tab est =rows(tab) soit 8 et le nombre de colonnes =columns(tab) soit 6 ... pour alléger la lecture on utilisera le résultat 8 et 6

=sequence(8;6;1;1)

donne donc

123456
789101112
131415161718
192021222324
252627282930
313233343536
373839404142
434445464748

ce qui permet un repérage des valeurs transformées par FLATTEN. On peut ainsi construire un tableau de correspondance en juxtaposant via \ les 2 colonnes

={flatten(sequence(8;6;1;1))\flatten(tab)}
1
2Lundi
3Mardi
4Mercredi
5Jeudi
6Vendredi
7Matt
8P
9P
10P
11P
12P
13Karim
14CP
15CP
16CP
17P
18P
19Tim
20
21
22F
23F
24F
25Gaëlle
26Mat
27Mat
28Mat
29Mat
30Mat
31Joachim
32EF
33EF
34P
35P
36P
37Marghe
38P
39P
40P
41RTT
42RTT
43Julie
44P
45P
46P
47P
48P

Dernier élément fondamental (on passera ensuite au mixage des éléments de "base") : repérer les en-têtes de colonnes et "en-têtes" de ligne.

Les en-têtes de colonnes (ici les jours) sont les éléments

1    2    3    4    5    6

c'est donc le reste de la division par 6 des valeurs précédentes, soit avec la fonction modulo

=arrayformula(mod(sequence(8;6;0;1);6)+1)
123456
123456
123456
123456
123456
123456
123456
123456

Les "en-têtes" de ligne (ici les noms) sont les éléments

1    7    13    19    25    31    37    43

qui s'obtiendront par la valeur entière de la division des valeurs précédentes par 6, soit :

=arrayformula(ROUNDDOWN(sequence(8;6;0;1)/6)*6+1)
111111
777777
131313131313
191919191919
252525252525
313131313131
373737373737
434343434343

on a tous les éléments pour combiner via des RECHERCHEV/VLOOKUP ... à suivre

Dernière étape ... utiliser les ingrédients vus plus haut :

en A et B : la liste des repères et des données de toutes les colonnes et lignes

=flatten(tab)

en D : la liste mise en colonne par flatten des repères des en-têtes de colonnes ... d'où en E les en-têtes elle-même issues de A,B par VLOOKUP

=arrayformula(vlookup(
mod(flatten(sequence(8;6;0;1));6)+1;
{flatten(sequence(8;6;1;1))\flatten(tab)};
2;0))

en G : la liste mise en colonne par flatten des repères des "en-têtes" de lignes ... d'où en H les en-têtes elle-même issues de A,B par VLOOKUP

=arrayformula(vlookup(
arrayformula(ROUNDDOWN(flatten(sequence(8;6;0;1))/6)*6+1);
{flatten(sequence(8;6;1;1))\flatten(tab)};
2;0))

le résultat attendu est donc en H, E et B (dans cet ordre) sur lequel on applique query pour ne pas retenir les lignes où une case est vide, ce qui enlève automatiquement les en-têtes de la colonne H

on remplacera aussi les valeurs 8 et 6 par rows(tab) et columns(tab)

ABCDEFGH
RepèreDonnéeJoursNoms
111
2Lundi2Lundi1
3Mardi3Mardi1
4Mercredi4Mercredi1
5Jeudi5Jeudi1
6Vendredi6Vendredi1
7Matt17Matt
8P2Lundi7Matt
9P3Mardi7Matt
10P4Mercredi7Matt
11P5Jeudi7Matt
12P6Vendredi7Matt
13Karim113Karim
14CP2Lundi13Karim
15CP3Mardi13Karim
16CP4Mercredi13Karim
17P5Jeudi13Karim
18P6Vendredi13Karim
19Tim119Tim
202Lundi19Tim
213Mardi19Tim
22F4Mercredi19Tim
23F5Jeudi19Tim
24F6Vendredi19Tim
25Gaëlle125Gaëlle
26Mat2Lundi25Gaëlle
27Mat3Mardi25Gaëlle
28Mat4Mercredi25Gaëlle
29Mat5Jeudi25Gaëlle
30Mat6Vendredi25Gaëlle
31Joachim131Joachim
32EF2Lundi31Joachim
33EF3Mardi31Joachim
34P4Mercredi31Joachim
35P5Jeudi31Joachim
36P6Vendredi31Joachim
37Marghe137Marghe
38P2Lundi37Marghe
39P3Mardi37Marghe
40P4Mercredi37Marghe
41RTT5Jeudi37Marghe
42RTT6Vendredi37Marghe
43Julie143Julie
44P2Lundi43Julie
45P3Mardi43Julie
46P4Mercredi43Julie
47P5Jeudi43Julie
48P6Vendredi43Julie

à noter que H aurait pu être obtenu comme E en transposant les données

=arrayformula(vlookup((roundup(flatten(sequence(6;8;1;1)/columns(tab))));{flatten(sequence(6;8;1;1))\flatten(transpose(tab))};2;0))

C'est pas simple, je le conçois et je ne suis pas sûr d'avoir été suffisamment didactique ! Mais refaire l'opération de A à Z peut-être un bon entraînement !! Enjoy.

Rechercher des sujets similaires à "google sheets transformer tableau liste exploitable facilement"