R3dKap
Expert Power AppsRéponses céées sur le Forum
-
Pour des gros volumes j’utilise Power Shell (avec SharePoint). Sais pas si ça existe pour Dataverse. Et c’est p’têt une fausse bonne idée… 😊
CommentID=yEm0KduBZFwf6vZ, PostID=3KQEiHzf1bmJDoY
-
Salut @Jesp,
Est-ce que tu peux cliquer sur le petit icône avec les deux flèches qui est par-dessus le libellé “Requête de filtre” et me mettre une capture de ce que cela affiche dans la zone juste en-dessous stp ?
Et puis me donner aussi le nom interne de ta colonne “Date réponse ?“.
CommentID=k6W7aWeUc77e268, PostID=7pBBBnFKK4oGtYW
-
R3dKap
Membre9 mars 2022 à 9h32 en réponse à: Enregistrement du "Screen" en PDF dans une liste SharepointOui c’est possible. Il faut que tu voies avec la personne de ton entreprise qui est Power Platform Admin ou juste Admin Global…
CommentID=uXEQ74Z7ttJISxv, PostID=ofR9qnVxIcg8WY2
-
@Laurent CARRIERE et @Ludovic je vais essayer de vous amener à comprendre pourquoi vous n’y arrivez pas afin de vous donner l’autonomie de le faire par vous-même par la suite…
En fait, il y a confusion dans les données que vous manipulez. Mais avant toute chose, il faudrait idéalement améliorer la nomenclature des objets et des variables parce-que là, même moi je m’y perds…
Ce que je recommande c’est d’utiliser en tout temps la nomenclature suivante (j’aimerais tellement que TOUS les développeurs Power Apps du monde entier suivent la même nomenclature… ce serait tellement plus simple pour se parler et lire le code des p’tits copains… 😀) :-
collection locale : colNomDeLaCollection (à définir avec les fonctions ClearCollect(), Collect(), Filter(), …)
-
variable globale : gloNomDeLaVariableGlobale (à définir avec la fonction Set())
-
variable locale : locNomDeLaVariableLocale (à définir avec la fonction UpdateContext())
-
colonne d’une liste SharePoint (nom interne) : scNomDeLaColonne (colonne à créer en 2 temps comme expliqué ici au paragraphe Création des colonnes)
Vous noterez au passage le jeu de majusucules/minuscules A RESPECTER pour plus de lisibilité… 😉
Pour en revenir à la formule qui ne fonctionne pas…
Si j’ai bien compris la manière dont sont organisées les données :
-
une liste RESERVOIR avec une colonne IDRESERVOIR de type texte (en gros c’est le catalogue des réservoirs)
-
une liste NETTOYAGE avec une colonne IDRESERVOIR de type recherche qui pointe vers la liste RESERVOIR (sur le champ IDRESERVOIR je suppose)
Là encore, déjà, aussi un petit souci de nomenclature :
-
la liste contenant TOUS les réservoirs devrait s’appeler RESERVOIRS au pluriel (c’est tout bête mais ça représente mieux la réalité et dans le code par la suite le fait de voir le pluriel me fait potentiellement comprendre plus facilement que c’est une liste) ; à la rigueur CatalogueReservoirs aurait même mieux… bref…
-
idem pour le nom de la liste NETTOYAGE qui serait mieux lotie avec un ‘S’
-
dans la liste NETTOYAGE, la colonne IDRESERVOIR est mal nommé car on ne nettoie pas un IDRESERVOIR mais un RESERVOIR -> donc autant l’appeler RESERVOIR tout simplement : en gros, le modèle de données, dans sa nomenclature, doit refléter la réalité (je nettoie quoi ? un réservoir -> j’appelle ma colonne RESERVOIR)
Et là on en arrive au plus important : la structure de cette colonne de recherche IDRESERVOIR de la liste NETTOYAGE. Comme vous le savez sa structure est la suivante :
{n Id: ...;n Value: ...n}
La première colonne Id va contenir la valeur de la colonne ID (remarquez ici les majuscules) de l’élément dans la liste liée RESERVOIR. Et la colonne Value va contenir la valeur de la colonne liée (ici IDRESERVOIR) de l’élément dans la liste RESERVOIR.
Voilà… Il faut bien avoir ça en tête au moment où on manipule les données.
Maintenant, supposons que l’on veuille mettre en place le filtrage proposé par @Ludovic. Pour rappel, l’idée c’est de filtrer la liste RESERVOIR pour ne conserver que les réservoirs qui ne sont jamais utilisés dans la liste NETTOYAGE (colonne de recherche IDRESERVOIR).
Donc, pour faire ça, on va donc écrire quelque chose qui ressemble à ça :
Filter(RESERVOIR; <condition de filtrage>)
La condition de filtrage va consister à regarder, pour le RESERVOIR en cours (en effet, n’oubliez pas que la fonction Filter() fonctionne comme une boucle où chaque élément de la collection en premier paramètre va être confronté à la condition spécifiée dans le 2è paramètre), s’il existe des lignes dans NETTOYAGE dont la colonne IDRESERVOIR pointe sur ce réservoir. S’il n’en existe aucune alors on “conserve” le réservoir en question et on sait qu’il n’a pas été nettoyé. On va utiliser la fonction CountIf() pour vérifier l’existence de ces lignes.
La formule se complète donc ainsi :
Filter(n RESERVOIR; n CountIf(NETTOYAGE; <condition de comptage>)=0n)
Que veux-t-on faire dans la condition de comptage ? On veut rechercher des éléments de NETTOYAGE où IDRESERVOIR pointe sur le réservoir en cours du Filter() (de la boucle). Or souvenez-vous, IDRESERVOIR dans NETTOYAGE c’est
{Id: <ID dans RESERVOIR>; Value: <IDRESERVOIR dans RESERVOIR>}
.Donc, ma condition va être la suivante :
IDRESERVOIR.Id = ID (celui de RESERVOIR)
Mais y’a un souci : il existe aussi une colonne ID dans NETTOYAGE. Comment Power Apps va savoir si ID c’est celui de RESERVOIR ou de NETTOYAGE dans notre formule ? Il y a ambiguïté… Pour résoudre ce problème, on a 2 solutions :
-
soit on utilise l’opérateur de désambiguïté :
IDRESERVOIR.Id = RESERVOIR[@ID]
(on précise que la colonne ID est celle de la liste RESERVOIR) -
soit on nomme temporairement la liste RESERVOIR dans la fonction Filter() pour pouvoir y faire référence ailleurs dans la formule :
Filter(RESERVOIR As ItemReservoir; ...)
et la condition du CountIf() serait alorsIDRESERVOIR.Id = ItemReservoir.ID
Je préfère la 2è solution. Et notre formule finale est donc la suivante :
Filter(n RESERVOIR As ItemReservoir; n CountIf(NETTOYAGE; IDRESERVOIR.Id = ItemReservoir.ID)=0n)
Au passage, lorsque je tape mon code je procède par étapes : j’écris les fonctions en partant du niveau le plus haut et je rentre en profondeur au fur et à mesure. Ca m’évite des erreurs de parenthèses et des oublis de paramètres. Et donc, j’écris les choses ainsi :
Filter(RESERVOIR As ItemReservoir; )
Puis :
Filter(RESERVOIR As ItemReservoir; CountIf()=0)
Puis :
Filter(RESERVOIR As ItemReservoir; CountIf(NETTOYAGE; IDRESERVOIR.Id = ItemReservoir.ID)=0)
Voilou… En espérant que vous avez bien suivi la logique et vous saurez l’appliquer à d’autres cas de figure… 😉
CommentID=sU0c4GHCY5Bgb5X, PostID=8LH1lVbKjN748zo
-
-
Au passage, la technique de Ludovic devrait marcher aussi… Y’a juste une p’tite erreur : c’est
IDRESERVOIR.Id
et pas justeIDRESERVOIR
et c’est= 0
et pas> 0
.Je sais pas trop laquelle est la plus performante… Celle de Ludo est plus élégante je trouve… 😉
CommentID=uT09UrSV40wTQaJ, PostID=8LH1lVbKjN748zo
-
@Laurent CARRIERE il faut que tu fasses comme ceci :
Filter(n reservoircollection;n Not(n ID in ShowColumns(n AddColumns(n nettoyagecollection;n "IdNettoyageReservoir";n IDRESERVOIR.Idn );n "IdNettoyageReservoir"n )n )n)
En effet, le IN doit avoir sur sa droite une table à une seule colonne. On construit donc cette table en récupérant l’Id de IDRESERVOIR dans nettoyagecollection dans une colonne dédiée (AddColumns()) et en ne conservant au final que cette colonne-là (ShowColumns()). A partir de là, on peut faire la négation sur le IN.
Si tu n’y arrives pas, poste une capture de ton erreur ici… 😉
CommentID=SRVq8HoF0DnfT5x, PostID=8LH1lVbKjN748zo
-
@Moon n’hésite pas à tagger les experts (ici) du domaine sur lequel tu poses ta question, comme par exemple @Aurelien, @Allan ou @Tanguy pour Dynamics 365. Ca te garantit qu’ils reçoivent un mail et augmente donc tes chances de réponses… 😋
Pas besoin de le refaire pour cette fois vu que je viens de le faire là… 😉
CommentID=Zv6x5IJhgCMX4oT, PostID=dPsbE68UuDtvOol
-
R3dKap
Membre8 mars 2022 à 11h14 en réponse à: PowerApps : fonction Launch() et choix du navigateurSi t’es prêt à modifier le registre des PC concernés :
CommentID=7cU1TKP79A05WEB, PostID=EgT8ae4aO0s4yzK
-
R3dKap
Membre8 mars 2022 à 10h57 en réponse à: PowerApps : fonction Launch() et choix du navigateurSalut @Vincent HERY,
Oui tout à fait, grâce à la fonction Launch(). Tout est détaillé ici :
Pour que ton lien s’ouvre dans Microsoft Edge tu peux formatter l’url de la manière suivante :
microsoft-edge:http://www.google.com
Mais si tu vises d’autres navigateurs, à priori ce n’est pas possible (sauf à monter une usine à gaz avec l’installation préalable de petits outils plus ou moins fiables).
Question (je creuse toujours le besoin, au cas où 😉) : pourquoi un navigateur spécifique ? Et si l’utilisateur n’a pas ce navigateur sur son poste ?
CommentID=Cn7mzRnYeRoHwEQ, PostID=EgT8ae4aO0s4yzK
-
R3dKap
Membre7 mars 2022 à 12h12 en réponse à: Résolu-Transfère d'une pièce jointe l'une liste à une autre@Hugotr35 en fait il faut déjà bien vérifier que ton modèle de données est bien pensé.
Est-ce que tu peux me préciser ce que tu as prévu pour l’instant comme listes et quelles sont les colonnes qui sont dans chaque liste ? En précisant le type de colonnes à chaque fois…
Parce-que de la manière dont tu structure tes données va dépendre la facilité (ou la difficulté) avec laquelle tu vas les manipuler via l’application…
CommentID=FWEXQXvDNAvgaKB, PostID=ktL2EZrQuMsf4yr
-
Merci pour l’astuce @Alexandre. Le seul inconvénient que je vois à cette technique c’est qu’au final ta sources de données se retrouve “derrière” la colonne Item par laquelle tu es obligé de passer pour accéder aux colonnes de ta source de données. Mais la technique est intéressante.
Toujours sur ce sujet, sans modifier la source de données, j’avais imaginé une autre technique avec un petit libellé à rajouter dans une galerie :
Il y a aussi une autre technique proposée par Matthew Devaney sur son blog, technique qui ressemble un peu à la tienne mais où il “dégroupe” le résultat final pour ne pas avoir justement sa source de données derrière une colonne “Item” :
CommentID=1BhIdilpoZFDI1O, PostID=GwtPOEVrD3YiCGN
-
Ouaip 😥
CommentID=hBJqIaRKrS0c5Jc, PostID=3KQEiHzf1bmJDoY
-
D’ailleurs j’ai fait le test :
-
j’ai créé une application vide
-
j’ai désactivé le Scale to fit
-
j’ai mis un text input sur l’écran
-
j’ai mis un text input dans un composant que j’ai aussi mis sur l’écran
Au lancement de l’application sur mon mobile j’ai bien des tailles de caractères identiques que ce soit dans le composant ou directement sur l’écran…
CommentID=QatpsMVI2urE9lm, PostID=Cng1lq2mFq0ugdx
-
-
@Alexandre @Didier ça m’a l’air un peu plus tricky que ça…
D’après cet article fort intéressant, il semblerait que le bon dimensionnement des caractères à l’écran dépende de la manière dont l’application est créée :
En gros, pour assurer un bon rendu quelque soit le format d’écran, il faut créer une application totalement vide (sans partir d’une source de données). Ensuite, la désactivation du Scale to fit est capitale pour la création d’une application responsive car elle garantit que cette dernière occupera tout l’espace disponible sur l’écran quelque soit sa taille et son orientation. Dans le cas contraire, le rapport largeur/hauteur est figé et tu peux donc te retrouver avec des bandes noires en haut et en bas de l’écran s’il na pas le même rapport que celui de ton application.
Voilou…
CommentID=am463nkBFT8LmpI, PostID=Cng1lq2mFq0ugdx
-
@Alexandre, effectivement cela reste possible (même dans un formulaire). Mais de base, c’est pas forcément optimisé en termes de perfs surtout lorsque c’est dans une galerie car celui-ci est alors répliqué autant de fois qu’il y a de lignes dans la galerie. En effet un composant pouvant potentiellement contenir pas mal de contrôle cela démultiplie rapidement le nombre de contrôles de l’application qui, selon la recommandation de Microsoft, ne devrait pas dépasser 500 pour la totalité de l’application.
Et pour le coup du paramètre qui passe mieux en utilisant un libellé, ça me surprend pas trop quand on pousse un peu Power Apps dans ses retranchements…
CommentID=3eWEb3er7622IEf, PostID=fmTDX87XLwo79qj