COMBOBOX interdépendants
-
COMBOBOX interdépendants
Séb a répondu Il y a 11 mois, 4 semaines 1 Membre · 28 Réponses
-
@S assure-toi de bien revenir sur mon message précédent ci-dessus passke j’ai galéré à le sauvegarder. J’ai dû m’y reprendre à plusieurs fois… 😉
CommentID=LzcKf51VoewIbXz, PostID=OwMnA3HFeAv42u0
-
@S je te confirme que pour que je puisse avancer maintenant, une fois que tu auras terminé les différentes étapes ci-dessus, c’est que l’on règle la problématique de la colonne des responsables.
Quel est le type de la colonne ? Et comment l’as-tu rendu multi-valeurs ?
Info très intéressante : on pourrait assez facilement créer une vraie colonne de type Personne multi-valeurs et copier/coller les noms des responsables que tu as actuellement dans ton tableau Excel. Il faut simplement que les noms des personnes dans ton fichier Excel correspondent aux noms des personnes dans l’AD de ton tenant, dans Microsoft 365. Et il suffit de les séparer par un point-virgule pour en mettre plusieurs.
Et là on serait nickel en termes de structuration de nos données.
On en rediscute…
CommentID=TAUYdNxsDpPwWof, PostID=OwMnA3HFeAv42u0
-
Bonjour @R3dKap ,
Et bien un grand merci déjà pour ces éléments et le temps consacré à rédiger cette 1er (longue) partie de réponse😀 👍 .
Concernant la colonne des responsables, les valeurs étaient rentrées en Texte dans Excel. (donc difficilement “matchables” avec l’AD même si on avait prénom et nom)
Lors de la création de la List SP, une nouvelle colonne de type Personne a été ajoutée après import des données à partir d’Excel.
Et pour chaque personne concernée, chaque valeur de l’AD a été saisie (pour chaque ligne) et l’option de sélection multiple a été activée directement dans les propriétés de ma colonne comme suit :
Je m’attaque aux travaux du matin que tu m’as donnés😉 et reviens vers toi pour la suite..
CommentID=6WVYxSmaV6kU4j4, PostID=OwMnA3HFeAv42u0
-
A mon tour de poser une petite question : pourquoi avoir copier/coller le code de l’activité (PM113,PM114…) dans la colonne ssActivité qui devrait contenir, à mon sens, le libellé du code (gérer les…, gérer les …,) ?
Et au passage, la sélection des valeurs de Titre en mode grille ne fonctionne pas de mon côté.
CommentID=eq6y9eemgSD5D3P, PostID=OwMnA3HFeAv42u0
-
Au temps pour moi, ça fonctionne !! 😅
Je suis donc prêt
CommentID=EBnMLonfjqkmzJ2, PostID=OwMnA3HFeAv42u0
-
Colonne scActivite
Pour répondre à ta question sur la colonne scActivite (attention “sc” pas “ss” et pas d’accent -> oui je suis hyper pointilleux sur la terminologie en général 😁)…
Lorsque tu crées une colonne de lookup (lookup = recherche en français dans SharePoint -> à retenir), la 2è liste déroulante que tu remplis dans les caractéristiques de la colonne représente le champ lié dans la liste cible, c’est à dire celui qui sera affiché dans la liste déroulante lorsque tu éditeras ou créeras un élément dans liste SharePoint via le formulaire natif (ou d’ailleurs celle d’un contrôle formulaire dans une application Power Apps).
Mais tu peux le changer si tu veux et pointer plutôt sur la colonne Titre pour afficher le libellé de l’activité en lieu et place du code. C’est juste que parfois les libellés peuvent être un peu long et que dans une liste déroulante ça peut ne pas être terrible visuellement…
A partir de maintenant, comme tu vas utiliser des lookups, retiens une seule chose hyper importante… Une colonne lookup est ce que l’on appelle “une colonne de type complexe” car elle a une structure interne plus complexe que simplement du texte, un nombre ou une date.
La structure d’un lookup est la suivante :
{n Id: <identifiant numérique>;n Value: <valeur>n}
La colonne Id représente l’identifiant SharePoint de l’élément dans la liste cible et la colonne Value la valeur du champ lié dans la liste cible (dont je parle précédemment).
Exemple…
Dans la liste Activités tu as ceci :
Dans la liste GestionActivites tu as ceci :
Eh bien pour la ligne encadrée en rouge, tu auras en interne dans ta colonne scActivite la valeur suivante :
{n Id: 2;n Value: "PM233"n}
Et si je venais à changer le champ lié de ma colonne scActivite pour le faire pointer sur la colonne scLibelle de la liste Activites, j’aurais ça :
{n Id: 2;n Value: "Piloter et gérer le contrôle"n}
Voilà… Là t’as les bases du fonctionnement des lookups…
Je te fais un autre post juste après sur le sujet de la colonne scResponsable…
CommentID=DEPdWNDkfvOBzTJ, PostID=OwMnA3HFeAv42u0
-
Colonne scResponsable
En réalité, ce que j’essayais de t’expliquer dans un de mes posts précédents, c’est que plutôt que de renseigner ta colonne de type Personne à la main avec les bonnes personnes en fonction de ce que tu as dans ton fichier Excel, il y aurait moyen de faire ça en une seule opération. J’explique…
Si dans ton fichier tu as dans ta colonne des responsables une cellule de texte dans laquelle tu as une valeur “Michel DURAND” et que dans l’AD de ton entreprise tu as bien un Michel DURAND (écrit pareil), si tu édites ta liste SharePoint en mode grille et que tu copies/colles/ “Michel DURAND” de ta cellule Excel vers la cellule de ta liste SharePoint dans la colonne de type Personne, il va te le transformer immédiatement en vraie personne Michel DURAND de ton AD.
Et mieux encore. En supposant que ta colonne de type Personne soit bien multi-valuée, si dans ta cellule Excel tu as “Michel DURAND;Pierre PAUL” et que tu as bien 2 comptes qui s’appellent comme ça dans l’AD, tu peux aussi les copier/coller dans ta liste en mode grille et il les transformeras tous les 2 en vrais comptes AD.
Du coup, il “suffirait” que tu mettes bien ton fichier Excel au propre (en faisant peut-être quelques chercher/remplacer) pour avoir les vrais bons noms des personnes, bien séparés avec des points-virgules et tu pourrais les copier/coller en une seule fois dans ta liste.
Tu me suis ?
Mais t’as déjà fait le boulot donc, avançons… 😉
CommentID=FUp5hhbMYYVjedn, PostID=OwMnA3HFeAv42u0
-
Du coup est-ce que tu peux me lister précisément les noms de tes listes et de tes colonnes (noms techniques) stp, sous ce format-ci par exemple :
Activites (nom dans l’url)
-
Titre (code de l’activité)
-
scLibelle (texte simple)
GestionActivites (nom dans l’url)
-
Titre (code de l’activité, ou autre)
-
scActivite (lookup)
-
scSousActivite (texte simple)
-
scResponsable (texte simple)
-
scResponsableAD (personne)
-
scEtat (choix)
Merci. Comme ça on se comprendra beaucoup mieux par la suite…
CommentID=BuZle2nuao5SUee, PostID=OwMnA3HFeAv42u0
-
-
1ère liste : PROCESSUS
-
Titre (code du processus)
-
LIBELLE (texte simple)
2e Liste : SAARA
-
Titre : (code du processu)
-
CODEPROCESSUS : lookup
-
ACTION : texte simple
-
PILOTE : texte simple
-
PILOTEAD : personne
-
ETAT : choix
J’avais “normalisé” les noms pour nos échanges😀 . Mais on parle de processus et d’actions associées avec un ou plusieurs pilotes de processus.
CommentID=RyNT5gi5LJ9uOLp, PostID=OwMnA3HFeAv42u0
-
-
Cher client,
Votre commande est prête et sa livraison est cours…
Livraison prévue le 31/01 dans la journée…
😉
CommentID=5eZYqWYAH7u4H7n, PostID=OwMnA3HFeAv42u0
-
@S petit retard dans la livraison… 🙏
Alors voilà les instructions…
Pour faire mon test j’ai créé des listes qui ont exactement les mêmes colonnes que toi. Mes 2 listes déroulantes s’appellent cbxProcessus et cbxPilotes. Ma galerie s’appelle galSaara et j’ai aussi un toggle nommé togFilterData.
Pour commencer, les 2 listes déroulantes sont alimentées comme ceci :
cbxProcessus.Items = Choices(SAARA.CODEPROCESSUS)nncbxPilotes.Items = Choices(SAARA.PILOTEAD)
Pour rappel, la structure d’un champ de type Personne est la suivante :
{n DisplayName: Blank();n Claims: "i:0#.f|membership|" & Lower(User().Email);n Department: Blank();n Email: Blank();n JobTitle: Blank();n Picture: Blank()n}
Pour la combo box cbxPilotes, j’affiche le champ DisplayName :
cbxPilotes.DisplayFields = ["DisplayName"]ncbxPilotes.SearchFields = ["DisplayName"]
Et bien sûr j’y ai activé la sélection multiple :
cbxPilotes.SelectMultiple = true
Ensuite, pour différentes raison que je vais essayer d’expliquer plus loin, je ne filtre pas la galerie directement sur la combo box des pilotes. Au lieu de cela, lorsque je change ma sélection de pilotes, je construis une collection colSaaraData avec les données filtrées.
Cette collection je la remplis dans l’événement OnChange du toggle togFilterData :
Clear(colSaaraData);nForAll(n cbxPilotes.SelectedItems As SelItem,n ForAll(n Filter(n AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn ),n (IsBlank(cbxProcessus.Selected) || CODEPROCESSUS.Value = cbxProcessus.Selected.Value) && SelItem.Claims in PilotesClaimsn ) As PiloteItem,n If(n Not(PiloteItem.ID in colSaaraData.ID),n Collect(n colSaaraData,n PiloteItemn )n )n )n)
Et donc sur la combo box cbxPilotes, dès lors qu’il y a un changement, je bascule une variable locale locFilterData qui va elle-même déclencher le OnChange du toggle togFilterData :
cbxPilotes.OnChange = UpdateContext({locFilterSaara: Not(locFilterSaara)})nntogFilterData.Default = locFilterSaara
Le OnChange tu toggle togFilterData qui filtre les données doit également être déclenché si je change de processus dans la liste déroulante cbxProcessus :
If(n Not(n IsEmpty(cbxPilotes.SelectedItems)n ), n UpdateContext({locFilterSaara: Not(locFilterSaara)})n)
On peut maintenant définir les éléments de la galerie. Pour cela, on considère 2 cas de figure : il n’y a aucun critère sur les pilotes et je filtre uniquement sur le processus ; dans tous les autres cas je dois filtrer à la fois sur les processus et les pilotes. Dans ce dernier cas, comme le travail est fait par le toggle, je me contente d’utiliser la collection qui en résulte.
Voici donc le code du Items de la galerie :
If(n IsBlank(cbxPilotes.Selected), n Filter(n SAARA, n IsBlank(cbxProcessus.Selected) || CODEPROCESSUS.Value = cbxProcessus.Selected.Value),n colSaaraDatan)
Voilà ce que ça donne au final :
Je te mets ci-joint le package de l’application que j’ai faite. Comme j’ai utilisé les mêmes colonnes que toi, il devrait te suffire de supprimer mes 2 listes et que tu mettes les 2 tiennes pour que l’appli marche de ton côté. Sinon, n’hésite pas à revenir vers moi.
Je vais expliquer dans un autre post ci-dessous la formule de filtrage du toggle…
CommentID=MSZ0BZgSh1PIafy, PostID=OwMnA3HFeAv42u0
-
Quelques explications donc sur cette formule qui s’occupe de faire le filtrage sur les pilotes :
Clear(colSaaraData);nForAll(n cbxPilotes.SelectedItems As SelItem,n ForAll(n Filter(n AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn ),n (IsBlank(cbxProcessus.Selected) || CODEPROCESSUS.Value = cbxProcessus.Selected.Value) && SelItem.Claims in PilotesClaimsn ) As PiloteItem,n If(n Not(PiloteItem.ID in colSaaraData.ID),n Collect(n colSaaraData,n PiloteItemn )n )n )n)
C’est le filtre sur les pilotes est à choix multiples qui complique tout évidemment. Cela nous oblige à boucler sur la liste des
cbxPilotes.SelectedItems
pour commencer.Pour chaque pilote qui figure dans cette table, il faut aller chercher les données correspondantes dans la liste, soit quelque chose comme ceci :
ForAll(n cbxPilotes.SelectedItems As SelItem,n Filter(n AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn ),n SelItem.Claims in PilotesClaimsn )n...
Remarque : la structure des données de la combo box cbxPilotes étant complexe (type Personne) à plusieurs colonnes on ne peut pas utiliser l’opérateur IN, ça ne marche pas :
ForAll( // ### Ceci ne marche pas !!!n cbxPilotes.SelectedItems As SelItem,n Filter(n SAARA,n SelItem in PILOTEADn )n...
C’est pour cette raison qu’on est obligé de rajouter à la source de données SAARA une colonne PilotesClaims avec le AddColumns() pour n’avoir dans cette colonne que les valeurs de Claims pour les pilotes sélectionnés :
AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn)
En imaginant que pour une ligne de SAARA j’ai 3 pilotes Pilote1, Pilote2 et Pilote3 dans la colonne PILOTEAD, la formule ci-dessus produit ce résultat :
Et du coup, là sur la colonne PilotesClaims je peux utiliser l’opérateur IN. Et donc je peux écrire ceci :
ForAll(n cbxPilotes.SelectedItems As SelItem,n Filter(n AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn ),n SelItem.Claims in PilotesClaimsn )n...
⛔ ATTENTION : le AddColumns() va faire appel au connecteur SharePoint pour ramener les données de la liste SAARA avant de lui ajouter la colonne. Or, quelque soit le connecteur, Power Apps ne ramènera jamais plus de 2000 lignes (paramètre de ton application qu’il faut passer de 500 à 2000). Conséquence : tout ce qu’on a construit depuis le début pour faire ce filtrage ne fonctionnera que si ta liste SAARA a moins de 2000 lignes.
Bref… La problématique suivante à laquelle on est confronté c’est qu’un pilote peut être sur plusieurs lignes de la liste SAARA. Ca veut que lors d’un premier passage du ForAll() ci-dessous je vais ramener les lignes 12, 27, 349 et 618 ; et lors d’un 2è passage je vais ramener une deuxième fois la ligne 349. Je me retrouve donc avec des doublons dans le résultat de mon filtrage !!!
Conséquence, il faut que je conditionne l’ajout d’une ligne à ma collection colSaaraData au fait qu’elle n’y est pas déjà. Je suis donc obligé de faire une 2è boucle à l’intérieur de la première pour que je puisse mettre en place cette condition :
ForAll(n cbxPilotes.SelectedItems As SelItem,n ForAll(n Filter(n AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn ),n SelItem.Claims in PilotesClaimsn ) As PiloteItem,n If(n Not(PiloteItem.ID in colSaaraData.ID),n Collect(n colSaaraData,n PiloteItemn )n )n )n)
Et pour terminer, il ne faut pas oublier qu’il se peut que j’ai sélectionné un filtre dans la combo box cbxProcessus avant de filtrer sur les pilotes. Il faut donc que j’en tienne compte que je fais mon filtre ici sur les pilotes, d’où l’ajout de la partie :
(IsBlank(cbxProcessus.Selected) || CODEPROCESSUS.Value = cbxProcessus.Selected.Value)
Et donc, la formule globale :
Clear(colSaaraData);nForAll(n cbxPilotes.SelectedItems As SelItem,n ForAll(n Filter(n AddColumns(n SAARA,n "PilotesClaims",n PILOTEAD.Claimsn ),n (IsBlank(cbxProcessus.Selected) || CODEPROCESSUS.Value = cbxProcessus.Selected.Value) && SelItem.Claims in PilotesClaimsn ) As PiloteItem,n If(n Not(PiloteItem.ID in colSaaraData.ID),n Collect(n colSaaraData,n PiloteItemn )n )n )n)
Voilou… Je me rends compte que c’est très compliqué à expliquer comme ça par écrit.
NOTE IMPORTANTE : si jamais ta liste dépasse les 2000 lignes, la seule solution pour s’en sortir c’est d’obliger l’utilisateur à filtrer D’ABORD sur le processus AVANT de filtrer sur les pilotes, tout en s’assurant que le premier filtrage sur le processus ne ramène pas plus, quant à lui, de 2000 lignes.
CommentID=UDFzTeuzTofokdW, PostID=OwMnA3HFeAv42u0
-
Bonjour @R3dKap ,
Encore une fois un GRAND MERCI 🙏 pour le contenu et la clarté de ta réponse. Je te suis vraiment reconnaissant du temps consacré à t’adapter à ma situation et à me proposer une solution personnalisée.
J’avais trouvé, en attendant, une solution palliative de mon côté (mais moins “chiadée”) et surtout qui ne permettait pas de sélectionner plusieurs pilotes. Et ça c’est vraiment un plus !!
Je vais donc adapter ton code à mon appli et reviendrais vers toi en cas de besoin.
Au fait je m’attendais à trouver du Lookup (du moins en clair) !!! 🤣 .
Et longue vie à cette plateforme d’entraide !!
Bien à toi,
Séb
CommentID=MrLXcL7tDsD7SG1, PostID=OwMnA3HFeAv42u0
Connectez-vous pour répondre.