Passer une étape en paramètre d’une fonction

Accueil – Le CFO masqué Forums Power Query Passer une étape en paramètre d’une fonction

  • Ce sujet contient 5 réponses, 2 participants et a été mis à jour pour la dernière fois par e.chevron, le il y a 2 années et 8 mois.
6 sujets de 1 à 6 (sur un total de 6)
  • Auteur
    Articles
  • #94193
    e.chevron
    Participant

    Bonjour à toutes et tous !

    Je cherche à créer une fonction qui sera utilisée en cours de traitement d’une table.
    Celle-ci est censée :

    1. Ajouter une colonne personnalisée
      Fusionner une requête existante avec le champ ajouté au point 1
      Déployer un champ de la requête fusionnée au point 2
      Supprimer la colonne créée au point 1
  • J’ai donc tenté la fonction suivante :

    let fxDistanceTrajet = (EtapePrecedente, NomChampDestination, Depart, Arrivee, NbTrajets) =>
        let
            #"AjoutTrajet" = Table.AddColumn(EtapePrecedente, "Provisoire", each (if Depart<>null and Arrivee<>null then
                                                                                                                    1 /*fxTrajet(Depart, Arrivee)*/
                                                                                                            else
                                                                                                                    null),
                                            Text.Type),
    
            AjoutDistance = Table.NestedJoin(AjoutTrajet, {"TrajetEtape"}, tableKm, {"Trajet"}, "tableKm", JoinKind.LeftOuter),
    
            DeveloppementDistance = Table.ExpandTableColumn(AjoutDistance, "tableKm", {"Distance"}, {"Distance"}),
    
            AjoutDistanceTotale = Table.AddColumn(DeveloppementDistance, NomChampDestination, each NbTrajets * [Distance], Int64.Type),
    
            DistanceTrajet = Table.RemoveColumns(AjoutDistanceTotale,{"Provisoire", "TrajetEtape", "Distance"})
        in
            AjoutTrajet
    in
        fxDistanceTrajet

    Avec pour paramètres :

    • EtapePrecedente : Nom de l’étape M précédente
      NomChampDestination : Nom du champ de destination
      Depart : Ville de départ
      Arrivee : Ville d’arrivée
      NbTrajets : Nombre de trajets effectués
  • Et appelée comme suit :

        <em>bla bla bla qui fonctionne</em>
        #"Renommage Distance Presta" = Table.RenameColumns(#"Suppression Trajet Presta",{{"Distance", "Distance Presta"}}),  // Fonctionne très bien
        #"Ajout Distance Totale" = fxDistanceTrajet(#"Renommage Distance Presta", "Test", [LIEU], [Etape 1], [Nb Etape 1]),

    Cette dernière étape me renvoyant l’erreur suivante :
    Expression.Error : Nous avons détecté un identificateur inconnu. Avez-vous utilisé la syntaxe raccourcie [field] pour un _[field] en dehors d’une expression « each » ?

    J’ai l’impression que le problème se situe au niveau du passage du nom de l’étape précédente en paramètre (j’ai tenté de mettre tout le code qui suit la première étape de la fonction en commentaire, j’obtiens la même erreur).

    L’intérêt de cette fonction est la répétition dans la séquence : J’ai un lieu de départ, un lieu de prestation, entre 0 et 3 étapes, un lieu de retour. Par exemple je vais donner une formation de 3 jours à 300KM de chez moi, puis une autre de 2 jours à 30 Km de la première, ça donne :
    Chez moi -> Tataouine les Bains,
    Tataouine les Bains -> Hôtel de la plage x 2 jour x 2 trajets (Aller + Retour),
    Tataouine les Bains -> Pétaouchnock les Alpilles
    Pétaouchnock les Alpilles -> Auberge de la Rivière au Bord de l’Eau x 1 jour x 2 trajets
    Pétaouchnock les Alpilles -> Chez moi

    Au niveau de mon tableau
    Départ : Maison
    Lieu : Tataouine les Bains
    Km Presta : 300
    Etape 1 : Hôtel de la plage
    Km Etape 1 : 300
    Nb Etape 1 : 2
    Etape 2 : Pétaouchnock les Alpilles
    Km Etape 2 : 30
    NbEtape 2 : 1
    Etape 3 : null
    Km Etape 3 : null
    Nb Etape 3 : null
    Retour : Maison

    Entre le lieu de presta et les éventuelles étapes, l’opération de fusion se répète potentiellement 4 fois, d’où l’idée d’en faire une fonction.

    En espérant ne pas vous avoir trop saoulés avec mes détails, et surtout que vous saurez m’expliquer pourquoi ça ne fonctionne pas, et vous remerciant par avance pour tout ça, je vous souhaite une excellente journée.

    Eric.

#94216
Stéphane Lorin
Participant

Bonjour
Désolé, il est difficile de vous aidez avec uniquement des copies de codes et des explications un peu complexes.

une piste : avez vous essayé de récupérer la distance via une formule du type
tablekm{[Trajet = [TrajetEtape]]}[Distance]
ou
tablekm{[Depart= [Lieu1]],[Arrivee= [Etape1]] }[Distance]

plutôt que par une fonction fusion/développement ?

mettez en ligne une version allégée de votre fichier au besoin.

Cordialement
Stéphane

#94219
e.chevron
Participant

Bonjour Stéphane, et merci pour cette réponse rapide.
.
Mon fichier est une usine avec laquelle je gère depuis plus de 10 ans les aspects financier et BPF (Bilan Pédagogique et Financier) de mon activité de formateur.
Ce n’est pas le côté confidentiel qui me dérange, il ne me faudrait que quelques minutes pour le rendre anonyme, mais son volume et sa complexité.
J’ai entrepris son évolution par l’utilisation de Power Query et Pivot à la fois pour l’optimiser et m’aguerrir à l’utilisation de ces outils pour lesquels la demande de formations s’amplifie (je suis formateur Office et VBA).
.
Bref, mes 30 ans de VBA m’aident pas mal à comprendre M, mais il reste néanmoins quelques syntaxes qui me restent mystérieuses, dont celle que vous utilisez dans votre proposition et qui va directement dans la direction que j’aurais justement adoptée en VBA : récupérer simplement une valeur en fonction d’une variable.
.
Du coup, j’ai pu analyser votre proposition et en tirer ceci :

Soit une requête tableKm :

  • [Trajet] text
  • [Distance] Int64

La fonction personnalisée suivante me permet bien de récupérer la valeur voulue dans la table via un comportement semblable à celui d’un RECHERCHEX() :

let fxDistanceTrajet = (CodeTrajet as text) =>
    let
        Resultat = tableKm{[Trajet=CodeTrajet]}[Distance]
    in
        Resultat
in fxDistanceTrajet

.
.
En revanche, l’utilisation des double-crochets me pose problème, et je ne comprends carrément pas la structure de tablekm{[Depart= [Lieu1]],[Arrivee= [Etape1]] }[Distance]
.
En terme de structure, et si je reprends la formule Resultat = tableKm{[Trajet=CodeTrajet]}[Distance], j’entends :
.
Résultat = TABLE{[Champ=Paramètre]}[Champ à récupérer]
.
Pourriez-vous développer de la même manière la structure de vos deux propositions ?
.
En vous remerciant pour votre aide fournie et celle à venir, bien cordialement,
Eric.

  • Cette réponse a été modifiée le il y a 2 années et 8 mois par e.chevron.
#94221
Stéphane Lorin
Participant

Je me suis trompé dans ma syntaxe pour filtrer sur 2 champs

au lieu de
tablekm{[Depart= [Lieu1]],[Arrivee= [Etape1]] }[Distance]

il faut

tablekm{[Depart= [Lieu1],Arrivee= [Etape1]]}[Distance]

pour obtenir la valeur du champ “distance” de la “tablekm” avec les conditions sur les champs “depart” et “arrivee”.
ça fonctionne s’il n’y a qu’un seul enregistrement en retour

Stéphane

#94222
Stéphane Lorin
Participant

en complément

Résultat = TABLE{[Champ1=Paramètre1, Champ2=Paramètre2]}
renvoie le seul enregistrement “Record” qui respecte la double condition “Champ1=Paramètre1, Champ2=Paramètre2”. Si plusieurs possibilités on obtient une erreur

l’ajout de [Champ à récupérer] à la fin permet d’obtenir le champ souhaité de cet enregistrement.

et pas besoin de faire une fonction dans votre cas je pense, vous pouvez obtenir le résultat directement dans votre requête.

  • Cette réponse a été modifiée le il y a 2 années et 8 mois par Stéphane Lorin.
#94224
e.chevron
Participant

C’est bien ce que j’avais cru comprendre.
En tout cas ça éclaircit bien les choses, et je t’en remercie beaucoup.

Ca servira sans doute à d’autres 😉

Bonne continuation.

6 sujets de 1 à 6 (sur un total de 6)
  • Vous devez être connecté pour répondre à ce sujet.