Bonnes pratiques création données HEADER / DETAIL

Étiquetté : , , ,

  • Bonnes pratiques création données HEADER / DETAIL

    Posté par Jeremy sur 16 juillet 2024 à 11h21

    Bonjour à tous,

    j’ai une question concernant votre façon de créer vos données dans le cadre d’une gestion en tables HEADER et DETAIL. (ici listes sharepoint).

    Voici un exemple que j’utilise pour une application d’audit, où la table AUDIT_HEADER contient des informations principales comme la date, l’auditeur, le secteur, etc; puis une table AUDIT_DETAIL avec la liste des points de l’audit avec la réponse de l’auditeur : conforme/non conforme, commentaire, photo, etc. (qui vient d’une autre liste).

    Ma démarche:

    • Faire la création du HEADER via formulaire
    • Utiliser le “OnSuccess” pour créer directement des enregistrement dans la table DETAIL notamment en récupérant le dernier ID dans la table AUDIT_HEADER via “Form.LastSubmit.ID”.
    • Les enregistrements créés sont ensuite compléter via des Patch directement sur la liste selon les réponses de l’auditeur.

    J’ai trouvé cette méthode en tatonnant, le fait d’utiliser le “OnSuccess” du formulaire me rassure dans la création du ID_HEADER, idem pour la création des enregistrements directement dans la liste dès le début, le fait de les savoir déjà créés me rassure pour la manipulation des données.

    Bref, comme Robert, j’aimerais muscler mon jeu (les vieux savent), et avoir vos bonnes pratiques dans ce cas de figure :

    • Utiliser GUID() plutot que les ID ?
    • Faire tout en collection et enregistrer tout à la fin du processus ?
    • Faire d’abord le DETAIL puis générer HEADER à la fin du processus ?
    • 🤷‍♂️

    Merci de vos retours.

    PS : j’ai déjà eu des problèmes avec la fonction LastSubmit (qui retourne vide dans tous les cas) avec certaines fonctionnalités en Preview.

    Sylvain a répondu Il y a 2 mois, 1 semaine 6 Membres · 10 Réponses
  • 10 Réponses
  • Quentin

    Membre
    16 juillet 2024 à 14h38

    Hello Jeremy,

    Pour ma part, sur un processus à plusieurs étapes comme ça, quand je dois le faire dans une app canevas, je privilégie l’utilisation d’un flux, ce qui me permet de :

    • Créer les éléments un par un (envoie des données aux flux, préalablement mise en collection) en les liant via des colonnes de recherche
    • M’assurer que les créations se font bien, dans le bon ordre, et que si la précédente a réussi (en utilisant le run after des actions dans mon flux Power Automate)
    • Notifier l’utilisateur en renvoyant à l’app tout ce qu’il s’est passé pour traiter les éventuelles erreurs
    • Faire un log dans une liste à part pour m’assurer du run du flux et monitorer

    En ce qui concerne tes questions suivantes :

    • si tu utilises les ID de sharepoint, la fonction GUID ne sera pas nécessaire à mes yeux
    • Faire tout en collection : oui, pour appeler ensuite un flux comme décrit précédemment 😉

    Et attention au LastSubmit, j’ai déjà eu en effet des soucis avec obligation de mettre un micro timer pour avoir la valeur apparaître dans mon app 🙁

    En espérant t’avoir éclairé 👍

  • Jeremy

    Membre
    17 juillet 2024 à 10h06

    Merci Quentin pour ta réponse, je vais creuser ce sujet.

    Tchô

  • Sylvain

    Membre
    7 septembre 2024 à 12h01

    Hello Jeremy,

    Comme on est en train de le voir il y a plusieurs manières de répondre à ce besoin et le fait d’en discuter sur un exemple concret comme celui là est vachement interessant :-).

    Je vais te dire comment j’aurai fait pour répondre à ce besoin par contre j’ai pas spécialement focalisé sur le sujet, disons que j’ai appri à faire des PowerApps sur le tas et que cette méthode fonctionne assez bien de mon côté pour que je n’ai pas eu à la remettre en question jusqu’à présent, mais très intéressé pour la confronter à d’autres méthodes :-). La réponse de Quentin a l’air très interessante à creuser dailleurs.

    Dans les grandes lignes voici mon approche :
    -> déjà je n’utilise JAMAIS les objets de type formulaire, je les trouve trop contraignant vis à vis de la customisation.

    -> Je travaille à l’intérieur d’une gallerie ou bien d’un conteneur à l’intérieur duquel je place l’ensemble des contrôles qui vont permettre de remplir la table detail

    -> j’ai tout le temps en // des collections tampons qui gèrent l’affichage et qui reflêtent les bases de données, et dès que j’agis sur un contrôle qui affecte la base de données j’ai en // :

    • le tampon sur la base de donnée (via patch)
    • la MAJ de la collection tampon d’affichage (via UPDATEIF)

    de fait lorsque l’utilisateur remplit des champs ils sont patchés en temps réel dans la BDD.

    La structure de mes tables seraient comme tu l’entends de ce que j’en ai compris :
    -> une table avec une ligne par formulaire, genre tableFormulaire

    -> une table pivot avec une ligne par réponse qui se réfèrent au formulaire, genre tablePivotReponseDansTableFormulaire

    Lorsque je génère un nouveau formulaire, donc une nouvelle ligne dans tableFormulaire, je génère la table et je récupère son ID directement sur une action de type :

    Creation de la nouvelle ligne et récupération de l’ID :

    Set(
    varIdTableFormulaire;
    Patch(
    tableFormulaire;
    Defaults(tableFormulaire);
    {
    date:Today()
    }
    ).ID

    );;

    Intégration de la nouvelle ligne dans la collection tampon :

    Collect(
    collTamponTableFormulaire;
    Filter(tableFormulaire;ID=varIdTableFormulaire)
    )

    -> il me semble qu’avec cette méthode si le patch ne marche pas alors je ne peut pas récupérer d’ID donc ça bloque, mais à ma connaissance ça marche toujours 🙂

    Je te laisse me dire ce que tu en penses 😉

  • DavidZed

    Membre
    7 septembre 2024 à 17h28

    Hello,

    Pour une appli similaire,

    J’ai un écran avec une gallerie qui affiche les audits en cours et un bouton “nouveau” qui mènent à l’écran suivant

    un écran avec le forumaire d’audit ( Header pour toi), un bouton submit

    un écran pour collecter les réponse : une question à la fois, l’écran boucle sur lui même, quand on est à la dernière question on a un option pour enregistrer ou envoyer

    Je n’ai pas de formulaire pour les points d’audit, seulement pour le header, dans son onsuccess, je stock le LastSubmit dans une variable et je fais un clearcollect des points d’audit.

    Les réponses sont mises à jour dans la collection et je patch la collection vers la table des points d’audit que quand l’utilisateur quitte l’écran de réponse.

  • Annie

    Membre
    8 septembre 2024 à 2h05

    WOW, ca faisait un bout que je n’étais pas venue, car en vacances, mais crime vous êtes tous à travailler des trucs que je dois faire dans les prochains mois. J’aimerais bien avoir un visuel de vos outils d’audit, car je n’ose pas pousser à demander un modèle mais je suis contente de connaitre ce forum. Bonne soirée.

  • Sylvain

    Membre
    8 septembre 2024 à 13h39

    Haha, bonne rentrée Annie 🙂

    Il me semble Jeremy que le fait d’avoir besoin d’enregistrement questions par question ou bien pas besoin d’enregistrement question par question mais plutôt à la fin de la manipulation devrait conditionner ton approche 😉

  • Jeremy

    Membre
    12 septembre 2024 à 21h21

    Bonsoir à tous, et merci pour toutes vos réponses.

    Rappel de mon shéma de départ :

    Avant j’aurais créé l’enregistrement du HEADER via un formulaire (car + simple et j’aime le “OnSuccess”), puis récupérer l’ID via un lastsubmit, pour ensuite lancer depuis l’appli la création des enregistrements des DETAIL via des ForAll/Patch/Default a partir d’un filtre sur la table TEMPLATE_5S.

    Mais au final, sur les conseils de Quentin, j’ai trouvé plus simple via un flow :

    1- En input, l’ID de la zone (ici moi j’ai aussi une notion de secteur [1 secteur possède plusieurs zones], je duplique l’information, plus simple pour les reports, je sais c’est pas super normalisé 😅)

    2- Je créé un element dans ma liste sharepoint HEADER, j’y injecte mes inputs ID Secteur et Zone

    3- Je filtre ma liste TEMPLATE_5S pour en extraire les lignes relatives à mon ID_Zone

    4- Pour chaque élément, je créé une ligne dans la table DETAIL, avec mon fameux ID_HDR provenant le la première opération

    5- Enfin, je demande au flow de me renvoyer en output l’ID_HDR pour que je puisse l’utiliser comme filtre dans mon application

    Dans l’application, pour lancer le flux (Crea_DTL) et récupérer l’ID_HDR dans une variable :

    <div>
    <div>Set(F_IDHDR;Crea_DTL.Run(ID_Zone;ID_Secteur).id_hdr_flux).</div>
    <div> </div>
    <div> </div>
    <div>Ensuite, concernant la mise à jour des données de l’audit, je préfère créer tout de suite les enregistrements dans la base, et les afficher via une gallerie (et non afficher une collection), et les patcher à chaque modification (OK/NOK, commentaire, photo, etc). J’aime bien l’idée que si un utilisateur, quitte l’application en cours d’audit (mauvaise manip ou il est appelé ailleurs), son travail n’est pas perdu. </div>
    <div> </div>
    <div>Merci à ceux qui sont restés jusque là :-p</div>
    </div>

  • R3dKap

    Membre
    12 septembre 2024 à 21h39

    @Jeremy, pourquoi un flux ? Ca me semble vachement compliqué à mettre en oeuvre (et à maintenir) alors que :

    • dans le OnSuccess du formHEADER tu pourrais initialiser toutes tes lignes de AUDIT DETAILS en faisant ceci :
      • tu boucles sur les lignes de AUDIT TEMPLATES qui correspondent au template spécifié dans le HEADER
      • tu crées (avec un simple Patch) une ligne AUDIT DETAILS en te servant de formHEADER.LastSubmit.ID et de la ligne de TEMPLATE en cours dans la boucle

    Ensuite l’appli n’a plus qu’à lister les lignes de AUDIT DETAILS pour qu’elles soient remplies par l’utilisateur (via un formulaire ou un simple Patch, au choix).

    PS: j’ai lu en diagonale que ton dernier post, donc j’ai p’têt loupé des trucs d’avant… 😉

  • Jeremy

    Membre
    12 septembre 2024 à 22h12

    C’est justement la solution que j’indique dans le premier poste 😉

    Aussi, je voulais trouver une alternative pour ne pas utiliser le LastSubmit car j’ai déjà eu des situations ou le lastSubmit ne me renvoit rien (quand certaines fonctionnalités en expérimental sont activées).

    Et puis je voulais aussi savoir comment font les gens plus malins que moi 😉

    C’est d’ailleurs la solution de Sylvain qui m’a 🤯

    Set(
    varIdTableFormulaire;
    Patch(
    tableFormulaire;
    Defaults(tableFormulaire);
    {}).ID

  • Sylvain

    Membre
    13 septembre 2024 à 16h50

    😆 merci, ça me touche, mais c’est un peu la base je crois 😅🤣 t’as déjà entendu parler d’un mec qui s’apelle : Young, Shane Young 😎🤣

Connectez-vous pour répondre.