EXCEL :: Regroupements et détails dynamiques en lignes et en colonnes d'un croisement par PIVOTER.PAR entièrement piloter par la fonction LET

  • Initiateur de la discussion Initiateur de la discussion oguruma
  • Date de début Date de début

Boostez vos compétences Excel avec notre communauté !

Rejoignez Excel Downloads, le rendez-vous des passionnés où l'entraide fait la force. Apprenez, échangez, progressez – et tout ça gratuitement ! 👉 Inscrivez-vous maintenant !

oguruma

XLDnaute Occasionnel
Bonjour le Forum,
dans un précédent post j'avais démontré comment obtenir le détail d'une ligne qui a été regroupée par la fonction GROUPER.PAR.
Dans la même idée ce post a pour but de pouvoir obtenir le détail d'une ligne et d'une colonne quand un tableau est construit par la fonction PIVOTER.PAR.
Voici un exemple. Le processus pour y arriver sera documenté largement dans les lignes suivantes. Je vous avoue qu'il y a quelques complexités sans aller trop loin néanmoins. Cela demande la maîtrise des fonctions LET, INDIRECT et DECALER.

1738419337122.png


La fonction LET en K10 gère intégralement la gestion de paramètres, leur contrôle et l'affichage.
1738419444402.png


Cela passe aussi par des paramètres généraux dans un onglet spécifique :
1738420187130.png

La base PIVOT c'est la 1ère ligne du regroupement des données. Ca sera le point de départ pour la fonction DECALER dans tout le code.


Préalables : créer les noms de champs des cellules sur fond VERT car ceux sont utilisé dans la fonction LET principale.

1738419739461.png


Certes, il est possible d'utiliser d'autres noms de champs à votre convenance mais ce cas il faudra intervenir dans toutes les formules !

Code de la fonction LET

Code:
=

=LET(
TBLE;NOM_TABLE_PIV;
FIELDV;"[" & PIVOTER_LIGNE & "]";
FIELDH;"[" & PIVOTER_COL & "]";
BASE_PIVOT;CELLULE_REF;
INDPIVOT;INDIRECT(BASE_PIVOT);
DEBUT_COL_DET;DEBUT_COL_DET;
FIN_COL_DET;FIN_COL_DET;
FIELDDISPLAY;"[[" & DEBUT_COL_DET & "]:[" & FIN_COL_DET &"]]";
INDFIELDV;TBLE&FIELDV;
INDFIELDH;TBLE&FIELDH;
INDISPLAY;TBLE&FIELDDISPLAY;
ENTETES;TBLE&"[[#En-têtes];["&DEBUT_COL_DET&"]:["&FIN_COL_DET&"]]";
TBLE_ENTETES;INDIRECT(ENTETES);
NB_COLS_ENTETES;NBVAL(TBLE_ENTETES);
NbLignes;NBVAL(UNIQUE(INDIRECT(INDFIELDV)));
NbCols;NBVAL(UNIQUE(INDIRECT(INDFIELDH)));
ListeLig;TRIER(UNIQUE(INDIRECT(INDFIELDV)));
ListeCols;TRIER(UNIQUE(INDIRECT(INDFIELDH)));
CheckBoxLignes;DECALER(INDPIVOT;;NbCols+2;NbLignes);
CheckBoxCols;TRANSPOSE(DECALER(INDPIVOT;-2;1;1;NbCols));
NbrCasesV;NBVAL(CheckBoxLignes);
NbrCasesH;NBVAL(CheckBoxCols);
NbrCasesHFalse;NB.SI(DECALER(INDPIVOT;-2;1;1;NbCols);FAUX);
NbrCasesHTrue;NB.SI(DECALER(INDPIVOT;-2;1;1;NbCols);VRAI);
NbrCasesVFalse;NB.SI(DECALER(INDPIVOT;;NbCols+2;NbLignes);FAUX);
NbrCasesVTrue;NB.SI(DECALER(INDPIVOT;;NbCols+2;NbLignes);VRAI);
CheckNbTrueOK;SI(OU(NbrCasesVTrue=0;NbrCasesHTrue=0);FAUX;VRAI);
CheckNbTrueUnic;SI(ET(NbrCasesVTrue=1;NbrCasesHTrue=1);VRAI;FAUX);
CheckNbFalseUnic;SI(OU(NbrCasesVTrue=0;NbrCasesHTrue=0);FAUX;VRAI);
CheckFinalOK;ET(CheckNbTrueOK;CheckNbTrueUnic);
currentRow;SIERREUR(EQUIVX(VRAI;CheckBoxLignes;0);-1);
currentColumn;SIERREUR(EQUIVX(VRAI;CheckBoxCols;0);-1);
currentValueLig;SIERREUR(INDEX(DECALER(INDPIVOT;;;NbLignes);currentRow);"ERREUR");
currentValueCol;SIERREUR(INDEX(DECALER(INDPIVOT;-1;1;1;NbCols);currentColumn);"ERREUR");
currentResult;INDEX(DECALER(INDPIVOT;;1;NbLignes;NbCols);currentRow;currentColumn);
tbl;SIERREUR(TRIER(FILTRE(INDIRECT(INDISPLAY);((INDIRECT(INDFIELDV)=currentValueLig)*(INDIRECT(INDFIELDH)=currentValueCol));""));"Erreur de traitement");
SI.CONDITIONS(
                PIVOTER_LIGNE="";"Renseigner le champ en ligne dans les paramètres";
                PIVOTER_COL="";"Renseigner le champ en colonne dans les paramètres";
                CELLULE_REF="";"Renseigner la cellule pivot dans les paramètres";
                DEBUT_COL_DET="";"Renseigner le champs début détail dans les paramètres";
                FIN_COL_DET="";"Renseigner le champ fin détail dans les paramètres";
                TBLE="";"Renseigner la table dans les paramètres";
                NbrCasesVTrue>1;"Choisir une seule ligne";
                NbrCasesHTrue>1;"Choisir une seule colonne";
                currentRow=-1;"Selectionner une ligne";
                currentColumn=-1;"Sélectionner une colonne";
                currentResult="";"Aucun résultat à détailler";
                CheckFinalOK;ASSEMB.V(TBLE_ENTETES;tbl))
)/CODE]
 

Pièces jointes

  • 1738419580102.png
    1738419580102.png
    3.4 KB · Affichages: 15
  • 1738421541676.png
    1738421541676.png
    4.6 KB · Affichages: 12
  • 1738421564322.png
    1738421564322.png
    9.6 KB · Affichages: 12
  • 1738421704629.png
    1738421704629.png
    9.6 KB · Affichages: 12
Dernière édition:
Suite

Comment cela fonctionne ?

On récupère ci-dessous :
- Le nom de la table à traiter
- les champs présentés en ligne et en colonne
- la base PIVOT qui sera nécessaire à la fonction DECALER
TBLE;NOM_TABLE_PIV;
FIELDV;"[" & PIVOTER_LIGNE & "]";
FIELDH;"[" & PIVOTER_COL & "]";
BASE_PIVOT;CELLULE_REF;

On initialise la cellule d'adressage de la base pivot pour la fonction DECALER
INDPIVOT;INDIRECT(BASE_PIVOT);

On récupère les colonnes qui seront affichées dans le détail
DEBUT_COL_DET;DEBUT_COL_DET;
FIN_COL_DET;FIN_COL_DET;
puis on le formate
FIELDDISPLAY;"[[" & DEBUT_COL_DET & "]:[" & FIN_COL_DET &"]]";

On prépare les paramètres lignes et colonnes qui seront nécessaires pour la fonction DECALER
INDFIELDV;TBLE&FIELDV;
INDFIELDH;TBLE&FIELDH;

On récupère le nom des en-têtes de colonne en préparant cette syntaxe
ENTETES;TBLE&"[[#En-têtes];["&DEBUT_COL_DET&"]:["&FIN_COL_DET&"]]";
On formate tout ceci
TBLE_ENTETES;INDIRECT(ENTETES);

Idem pour le nombre de colonnes que comporte les en-têtes (non utilisé pour l'instant)
NB_COLS_ENTETES;NBVAL(TBLE_ENTETES);

On calcule le Nbr de lignes et colonnes produits par la fonction PIVOTER.PAR
NbLignes;NBVAL(UNIQUE(INDIRECT(INDFIELDV)));
NbCols;NBVAL(UNIQUE(INDIRECT(INDFIELDH)));

On les identifie comme suit
ListeLig;TRIER(UNIQUE(INDIRECT(INDFIELDV)));
ListeCols;TRIER(UNIQUE(INDIRECT(INDFIELDH)));

On prépare les contrôles pour éviter des plantages de la fonction
CheckBoxLignes;DECALER(INDPIVOT;;NbCols+2;NbLignes);
CheckBoxCols;TRANSPOSE(DECALER(INDPIVOT;-2;1;1;NbCols));
NbrCasesV;NBVAL(CheckBoxLignes);
NbrCasesH;NBVAL(CheckBoxCols);
NbrCasesV;NBVAL(CheckBoxLignes);
NbrCasesH;NBVAL(CheckBoxCols);
NbrCasesHFalse;NB.SI(DECALER(INDPIVOT;-2;1;1;NbCols);FAUX);
NbrCasesHTrue;NB.SI(DECALER(INDPIVOT;-2;1;1;NbCols);VRAI);
NbrCasesVFalse;NB.SI(DECALER(INDPIVOT;;NbCols+2;NbLignes);FAUX);
NbrCasesVTrue;NB.SI(DECALER(INDPIVOT;;NbCols+2;NbLignes);VRAI);
CheckNbTrueOK;SI(OU(NbrCasesVTrue=0;NbrCasesHTrue=0);FAUX;VRAI);
CheckNbTrueUnic;SI(ET(NbrCasesVTrue=1;NbrCasesHTrue=1);VRAI;FAUX);
CheckNbFalseUnic;SI(OU(NbrCasesVTrue=0;NbrCasesHTrue=0);FAUX;VRAI);
CheckFinalOK;ET(CheckNbTrueOK;CheckNbTrueUnic);

On détermine qu'elle est la ligne sélectionnée
currentRow;SIERREUR(EQUIVX(VRAI;CheckBoxLignes;0)

On détermine qu'elle est la colonne sélectionnée
currentColumn;SIERREUR(EQUIVX(VRAI;CheckBoxCols;0);-1);

On récupère les champs sélectionnés en ligne et en colonne
currentValueLig;SIERREUR(INDEX(DECALER(INDPIVOT;;;NbLignes);currentRow);"ERREUR");
currentValueCol;SIERREUR(INDEX(DECALER(INDPIVOT;-1;1;1;NbCols);currentColumn);"ERREUR");

On récupère la valeur de l'intersection ligne/colonne
currentResult;INDEX(DECALER(INDPIVOT;;1;NbLignes;NbCols);currentRow;currentColumn);

On effectue les recherches via un FILTRAGE en fonction des paramètres fournis et des résultats de traitements précédents
tbl;SIERREUR(TRIER(FILTRE(INDIRECT(INDISPLAY);((INDIRECT(INDFIELDV)=currentValueLig)*(INDIRECT(INDFIELDH)=currentValueCol));""));"Erreur de traitement");

et enfin....
après quelques contrôles on précède à l'affichage ET C'EST FINI !!!
Simple non ? 🙂
Bon j'avoue que j'ai passé un peu temps pour mettre cela au point 🙂

SI.CONDITIONS(
PIVOTER_LIGNE="";"Renseigner le champ en ligne dans les paramètres";
PIVOTER_COL="";"Renseigner le champ en colonne dans les paramètres";
CELLULE_REF="";"Renseigner la cellule pivot dans les paramètres";
DEBUT_COL_DET="";"Renseigner le champs début détail dans les paramètres";
FIN_COL_DET="";"Renseigner le champ fin détail dans les paramètres";
TBLE="";"Renseigner la table dans les paramètres";
NbrCasesVTrue>1;"Choisir une seule ligne";
NbrCasesHTrue>1;"Choisir une seule colonne";
currentRow=-1;"Selectionner une ligne";
currentColumn=-1;"Sélectionner une colonne";
currentResult="";"Aucun résultat à détailler";
CheckFinalOK;ASSEMB.V(TBLE_ENTETES;tbl))
)


Règles de construction
Placer les cases cocher comme ci-dessous :

Dans le cas contraire il faudra intervenir dans les fonctions permettant de déterminer la plage des cases à cocher horizontales et verticales. Débutants Excel s'abstenir 🙂
1738422114672.png

Exemples de contrôles
1738422171859.png


1738422193266.png


1738422215899.png


1738422232379.png


1738422258276.png


1738422304602.png


1738422328684.png
 
Dernière édition:
Suite :
Une fonction LET permet de gérer ceci :
1738422439020.png

=LET(
TBLE;NOM_TABLE_PIV;
FIELDV;"["&PIVOTER_LIGNE&"]";
FIELDH;"["&PIVOTER_COL&"]";
BASE_PIVOT;CELLULE_REF;
INDPIVOT;INDIRECT(BASE_PIVOT);
INDFIELDV;TBLE&FIELDV;
INDFIELDH;TBLE&FIELDH;
NbLignes;NBVAL(UNIQUE(INDIRECT(INDFIELDV)));
NbCols;NBVAL(UNIQUE(INDIRECT(INDFIELDH)));
CheckBoxLignes;DECALER(INDPIVOT;;NbCols+2;NbLignes);
CheckBoxCols;TRANSPOSE(DECALER(INDPIVOT;-2;1;1;NbCols));
currentRow;SIERREUR(EQUIVX(VRAI;CheckBoxLignes;0);"");
currentColumn;SIERREUR(EQUIVX(VRAI;CheckBoxCols;0);"");
currentValueLig;SIERREUR(INDEX(DECALER(INDPIVOT;;;NbLignes);currentRow);"");
currentValueCol;SIERREUR(INDEX(DECALER(INDPIVOT;-1;1;1;NbCols);currentColumn);"");
"Détail pour : " & currentValueLig & "/" & currentValueCol & " - ligne : " & currentRow & " - colonne : " & currentColumn)

Il y également la construction dynamique de la fonction PIVOTER.PAR
=LET(
TBLE;NOM_TABLE_PIV;
FIELDV;"["&PIVOTER_LIGNE&"]";
FIELDH;"["&PIVOTER_COL&"]";
FIELDVAL;"["&PIVOTER_VAL&"]";
TOUT;"[#Tout]";
TOT_LIGNE;SI(TOTAUX_LIGNE="OUI";1;0);
TOT_COL;SI(TOTAUX_COL="OUI";1;0);
OPER;TYPE_OPER;
INDFIELDV;TBLE&"["&TOUT&";"&FIELDV&"]";
INDFIELDH;TBLE&"["&TOUT&";"&FIELDH&"]";
INDFIELDVAL;TBLE&"["&TOUT&";"&FIELDVAL&"]";
pivotBY;PIVOTER.PAR(
INDIRECT(INDFIELDV);
INDIRECT(INDFIELDH);
INDIRECT(INDFIELDVAL);
SI.MULTIPLE(OPER;"NBVAL";NBVAL;"SOMME";SOMME;"MOYENNE";MOYENNE;"MAX";MAX;"MIN";MIN;SOMME);
1;TOT_LIGNE;SI(TRI_LIGNE="";;TRI_LIGNE);TOT_COL;SI(TRI_COL="";;TRI_COL);SI(OU(CHAMP_FILTRE="";VALEUR_FILTRE="");;INDIRECT(NOM_TABLE_PIV&"["&CHAMP_FILTRE&"]")=VALEUR_FILTRE));
SIERREUR(pivotBY;"ERREUR DANS LE PARAMETRAGE !!!"))

Exemple
1738422603945.png

1738422623136.png


1738422639759.png
est géré par cette fonction LET
=LET(
TBLE;NOM_TABLE_PIV;
FIELDV;"["&PIVOTER_LIGNE&"]";
FIELDH;"["&PIVOTER_COL&"]";
FIELDVAL;"["&PIVOTER_VAL&"]";
TOUT;"[#Tout]";
INDFIELDV;TBLE & "[" & TOUT & ";" & FIELDV & "]";
INDFIELDH;TBLE & "[" & TOUT & ";" & FIELDH & "]";
INDFIELDVAL;TBLE & "[" & TOUT & ";" & FIELDVAL & "]";
FIELDV & "/" & FIELDH
)

1738422723945.png

Selon le champ choisi en ligne il faudra ajouter ou supprimer des cases à cocher
Selon le champ choisi en colonne il faudra décaler un nombre de colonne suffisant pour éviter le message PROPAGATION c'est-à-dire qu'Excel n'a pas trouver la place pour afficher les colonnes.
1738422853571.png

Enfin on peut intervenir sur :
- données à filter
- affichage des totaux en lignes et en colonne
- et les colonnes à trier. Rappel : nombre négatif = tri décroissant.
1738422895849.png
 

Pièces jointes

Dernière édition:
Bonjour,
pour information ces fonctions sont disponibles dans la version Office 2021.
En revanche pour aller plus loin.... les fonctions comme LAMBA, MAKEARRAY, MAP disponibles dans O365 ne sont pas disponibles dans la version 2021.. tout au moins dans la mienne bien que j'ai fait les maj.
Etrange GROUPER.PAR et PIVOTER.PAR sont apparues bien après ou tout au moins dans les mêmes créneaux.... et elles n'ont pas été implémentées dans cette version.
Quid de la version 2024 ? qui a installé cette version ?
Je vais tenter l'installation sur une VM Windows10
 
Bonjour,
Sous 2024, GROUPER.PAR et PIVOTER.PAR ne sont pas disponibles
Comme tout plein d'autres (SUPPR.PLAGE, Regex...)
LAMBA, MAKEARRAY, MAP, REDUCE sont, elles, dispos dans 2024 (entre autres, liste non exhaustive)
 
Bonjour,
Sous 2024, GROUPER.PAR et PIVOTER.PAR ne sont pas disponibles
Comme tout plein d'autres (SUPPR.PLAGE, Regex...)
LAMBA, MAKEARRAY, MAP, REDUCE sont, elles, dispos dans 2024 (entre autres, liste non exhaustive)
Bonjour,
je crois que tout est fait pour embarquer les utilisateurs vers des abonnements O365, perso j'ai l'abonnement à 100 € par an.... je voudrais bien m'en passer 😉 - certes pas énorme mais si je pouvais les mettre ailleurs 😉
 
- Navigue sans publicité
- Accède à Cléa, notre assistante IA experte Excel... et pas que...
- Profite de fonctionnalités exclusives
Ton soutien permet à Excel Downloads de rester 100% gratuit et de continuer à rassembler les passionnés d'Excel.
Je deviens Supporter XLD
Retour