Power Query Appeler plusieurs requêtes API basées sur la colonne d'une requête précédente

jymjams75

XLDnaute Nouveau
Bonjour à toutes et à tous,
J'ai deux API liées.
- une API permet une liste de campagnes envoyées qui ont chacune un identifiant (IDCAMPAGNE)
- une autre API, qui contient dans son URL l'identifiant récupéré dans la première API, et qui permet de récupérer les statistiques d'une campagne.

En gros, la première API me remonte XX lignes, qui correspondent à XX campagnes
Et je veux lancer automatiquement lancer XX requêtes sur la deuxième API (url = blablabla.com/IDCAMPAGNE) pour remonter les données de chacune des campagnes.

Je ne sais pas par où commencer :(
Auriez-vous une idée ?
 

Hasco

XLDnaute Barbatruc
Repose en paix
Bonjour,

Faites la première requête avec la première api.
Faites une requête avec la deuxième api et un identifiant connu.
Transformer cette dernière en fonction paramétrée
Ajouter une colonne à la première requête en appelant la fonction faite avec la deuxième api
Développer les lignes des tables retournées dans la colonne.

Cordialement
 

jymjams75

XLDnaute Nouveau
Bonjour Hasco et merci :)

Question complémentaire : "transformer cette dernière en fonction paramétrée"...c'est-à-dire ?
Je suis débutant sur Query.
Je vois ce que sont les paramètres mais je ne suis pas tout à fait sûr de bien comprendre votre phrase.

Désolé et merci
 

Hasco

XLDnaute Barbatruc
Repose en paix
Re,

Une fois que votre requête utilisant l'api2 est au point (y compris les transformations finales)
Dans le volet gauche de PQ faites un click-droit sur son nom, choisissez requête.
PQ va vous dire qu'il ne trouve aucun paramètre et vous demander si vous voulez créer quand même la fonction. Cliquez sur 'Créer'. Donnez un nom explicite à votre fonction (par exemple: fnApi2)

Editez votre fonction en mode 'Avancé' (Affichage/Editeur Avancé).
La structure de votre requête ressemblera à ça :
Code:
let
    Source = (NomTable as text) => let
        Source = Excel.CurrentWorkbook(){[Name=NomTable]}[Content],
        // Empiler les colonnes par 2
        Personnalisé1 = Table.Combine( List.Transform( List.Split(Table.ColumnNames(Source),2), each Table.Skip(Table.DemoteHeaders( Table.SelectColumns(Source,_)),1))),
        #"Colonnes renommées" = Table.RenameColumns(Personnalisé1,{{"Column1", "Achats"}, {"Column2", "Ventes"}}),
        #"Personnalisée ajoutée" = Table.AddColumn(#"Colonnes renommées", "Semaine", each if [Ventes]=null then [Achats] else null),
        #"Rempli vers le bas" = Table.FillDown(#"Personnalisée ajoutée",{"Semaine"}),
        #"Lignes filtrées" = Table.SelectRows(#"Rempli vers le bas", each ([Ventes] <> null) and ([Ventes]<>"Ventes"))
    in
        #"Lignes filtrées"
in
    Source

Entre les parenthèses de la ligne :
Source = (NomTable as text) => let
Mettez votre nom de paramètre et son type pour qu'elle ressemble à ça :
Source = (Identifiant as text) =>
Puis modifiez ce qui est nécessaire à l'étape suivant pour que votre paramètre soit pris en compte
Ici j'ai choisi 'text' comme type parce que le paramètre sera passé à une URI textuelle (celle de votre deuxième api)
Validez vos changements.

Dans la requête de la première API rajoutez une colonne personnalisée avec pour formule '= fnApi2([ColonneIdentifiant]) '

Validez

Où ColonneIdentifiant est le nom de la colonne qui contient l'identifiant que vous voulez passez à votre deuxième requête.

Si vous avez des difficultés, faites nous un classeur exemple avec vos deux requêtes.

Cordialement

P.S. la fonction précédente peut être réduite manuellement à :
Code:
 (NomTable) => let
        Source = Excel.CurrentWorkbook(){[Name=NomTable]}[Content],
        // Empiler les colonnes par 2
        Personnalisé1 = Table.Combine( List.Transform( List.Split(Table.ColumnNames(Source),2), each Table.Skip(Table.DemoteHeaders( Table.SelectColumns(Source,_)),1))),
        #"Colonnes renommées" = Table.RenameColumns(Personnalisé1,{{"Column1", "Achats"}, {"Column2", "Ventes"}}),
        #"Personnalisée ajoutée" = Table.AddColumn(#"Colonnes renommées", "Semaine", each if [Ventes]=null then [Achats] else null),
        #"Rempli vers le bas" = Table.FillDown(#"Personnalisée ajoutée",{"Semaine"}),
        #"Lignes filtrées" = Table.SelectRows(#"Rempli vers le bas", each ([Ventes] <> null) and ([Ventes]<>"Ventes"))
    in
        #"Lignes filtrées"
(PQ rajoute parfois des choses inutiles)
 

Hasco

XLDnaute Barbatruc
Repose en paix
Dernière édition:

jymjams75

XLDnaute Nouveau

Hasco, merci pour votre réactivité et vos explications.​

J'avance pas mal...grâce à vous.

Malheureusement, les données sont confidentielles, je ne peux pas vous passer le fichier Excel...ce qui m'aiderait pourtant :)

J'ai réussi à créer la fonction : je remonte bien dans ma première API les colonnes supplémentaires liées à la seconde (pour l'instant une requête spécifique)

En revanche, je n'arrive pas à savoir ce que je dois modifier dans l'éditeur avancé de la fonction.

VB:
let
    Source = () => let
        Source = Json.Document(Web.Contents(" https://MONAPI.com/reports/lg8QMJR9aqJa_thQ")),
        #"Converti en table" = Record.ToTable(Source),
        #"Value développé" = Table.ExpandRecordColumn(#"Converti en table", "Value", {"date", "overview"}, {"Value.date", "Value.overview"}),
        #"Value.overview développé" = Table.ExpandRecordColumn(#"Value développé", "Value.overview", {"count", "opens", "openers", "shared", "os", "device", "read", "actives", "hasLinks", "clicks", "clickers"}, {"Value.overview.count", "Value.overview.opens", "Value.overview.openers", "Value.overview.shared", "Value.overview.os", "Value.overview.device", "Value.overview.read", "Value.overview.actives", "Value.overview.hasLinks", "Value.overview.clicks", "Value.overview.clickers"}),
        #"Value.overview.read développé" = Table.ExpandRecordColumn(#"Value.overview développé", "Value.overview.read", {"interest"}, {"Value.overview.read.interest"}),
        #"Value.overview.device développé" = Table.ExpandRecordColumn(#"Value.overview.read développé", "Value.overview.device", {"desktop"}, {"Value.overview.device.desktop"}),
        #"Value.overview.os développé" = Table.ExpandRecordColumn(#"Value.overview.device développé", "Value.overview.os", {"values"}, {"Value.overview.os.values"}),
        #"Value.overview.os.values développé" = Table.ExpandRecordColumn(#"Value.overview.os développé", "Value.overview.os.values", {"Windows"}, {"Value.overview.os.values.Windows"}),
        #"Colonnes supprimées" = Table.RemoveColumns(#"Value.overview.os.values développé",{"Value.overview.shared"})
    in
        #"Colonnes supprimées"
in
    Source

Est-ce bien au niveau de l'URL que je dois faire une modification pour enlever "lg8QMJR9aqJa_thQ" et y glisser un paramètre à la place ?

Merci
 

Hasco

XLDnaute Barbatruc
Repose en paix
Re,

Euh ! ? Je ne peux pas deviner quel paramètre de l'url va changer d'une ligne à l'autre.
C'est vous qui connaissez votre affaire.

Si 'lg8QMJR9aqJa_thQ' est effectivement l'identifiant d'un document qui change d'une ligne à l'autre alors : (je vous mets la forme raccourcie, sans le let .... in extérieur qui ne sert à rien )
(IdentifiantDocument as text ) =>
let
Source = Json.Document(Web.Contents(" https://MONAPI.com/reports/" & IdentifiantDocument ) ),
#"Converti en table" = Record.ToTable(Source),
#"Value développé" = Table.ExpandRecordColumn(#"Converti en table", "Value", {"date", "overview"}, {"Value.date", "Value.overview"}),
#"Value.overview développé" = Table.ExpandRecordColumn(#"Value développé", "Value.overview", {"count", "opens", "openers", "shared", "os", "device", "read", "actives", "hasLinks", "clicks", "clickers"}, {"Value.overview.count", "Value.overview.opens", "Value.overview.openers", "Value.overview.shared", "Value.overview.os", "Value.overview.device", "Value.overview.read", "Value.overview.actives", "Value.overview.hasLinks", "Value.overview.clicks", "Value.overview.clickers"}),
#"Value.overview.read développé" = Table.ExpandRecordColumn(#"Value.overview développé", "Value.overview.read", {"interest"}, {"Value.overview.read.interest"}),
#"Value.overview.device développé" = Table.ExpandRecordColumn(#"Value.overview.read développé", "Value.overview.device", {"desktop"}, {"Value.overview.device.desktop"}),
#"Value.overview.os développé" = Table.ExpandRecordColumn(#"Value.overview.device développé", "Value.overview.os", {"values"}, {"Value.overview.os.values"}),
#"Value.overview.os.values développé" = Table.ExpandRecordColumn(#"Value.overview.os développé", "Value.overview.os.values", {"Windows"}, {"Value.overview.os.values.Windows"}),
#"Colonnes supprimées" = Table.RemoveColumns(#"Value.overview.os.values développé",{"Value.overview.shared"})
in
#"Colonnes supprimées"

Et dans l'autre requête ajoutez une colonne appelant votre fonction en lui passant entre crochets le nom de la colonne qui contient l'identifiant du document.

=NomDeMaFonction([NomDeLaColonneDeCetteTableQuiContientIdentifiantDocument])
:)

Avez-vous vu mon message avec les liens vers les aides microsoft ?

Cordialement
 

jymjams75

XLDnaute Nouveau
Bonjour,
et encore merci.
J'ai tout lu - pas encore tout compris mais presque.

j'ai créé la colonne pour invoquer la fonction. Problème ce sont des informations de type "fonction" qui apparaissent dans ma colonne
1633597793798.png


Quand je clique sur chacune des lignes, ce sont les bonnes infos qui remontent...mais comment les extraire dans mon tableau ?
 

Hasco

XLDnaute Barbatruc
Repose en paix
Bonjour,

Eh bien c'est déjà pas mal.
Il faudrait voir comment vous avez écrit votre fonction et comment vous l'appelez sur chaque ligne.
normalement votre étape devrait ressembler à ça :

Table.AddColumn(#"Etape précédente", "fnApi", each fnApi([NomColonneDeLaValeurDuParamètre]))

Cordialement
 
Dernière édition:

jymjams75

XLDnaute Nouveau
L'appel est ok, il correspond à ce que vous avez écrit.
J'en déduis donc que c'est dans ma fonction que j'ai fait n'importe quoi... :(
VB:
(Identifiant as text ) =>
let
    Source = () => let
    Source = Json.Document(Web.Contents("https://monapi.com/reports/" & Identifiant)),
    #"Converti en table" = Record.ToTable(Source),
    #"Value développé" = Table.ExpandRecordColumn(#"Converti en table", "Value", {"date", "overview"}, {"Value.date", "Value.overview"}),
    #"Value.overview développé" = Table.ExpandRecordColumn(#"Value développé", "Value.overview", {"count", "opens", "openers", "shared", "os", "device", "read", "actives", "hasLinks", "clicks", "clickers"}, {"Value.overview.count", "Value.overview.opens", "Value.overview.openers", "Value.overview.shared", "Value.overview.os", "Value.overview.device", "Value.overview.read", "Value.overview.actives", "Value.overview.hasLinks", "Value.overview.clicks", "Value.overview.clickers"}),
    #"Value.overview.read développé" = Table.ExpandRecordColumn(#"Value.overview développé", "Value.overview.read", {"interest"}, {"Value.overview.read.interest"}),
    #"Value.overview.device développé" = Table.ExpandRecordColumn(#"Value.overview.read développé", "Value.overview.device", {"desktop"}, {"Value.overview.device.desktop"}),
    #"Value.overview.os développé" = Table.ExpandRecordColumn(#"Value.overview.device développé", "Value.overview.os", {"values"}, {"Value.overview.os.values"}),
    #"Value.overview.os.values développé" = Table.ExpandRecordColumn(#"Value.overview.os développé", "Value.overview.os.values", {"Windows"}, {"Value.overview.os.values.Windows"}),
    #"Colonnes supprimées" = Table.RemoveColumns(#"Value.overview.os.values développé",{"Value.overview.shared"})
in
    #"Colonnes supprimées"
in
    Source
 

Hasco

XLDnaute Barbatruc
Repose en paix
Re,

Essayez çà :
VB:
(Identifiant as text ) =>
let
    Source = Json.Document(Web.Contents("https://monapi.com/reports/" & Identifiant)),
    #"Converti en table" = Record.ToTable(Source),
    #"Value développé" = Table.ExpandRecordColumn(#"Converti en table", "Value", {"date", "overview"}, {"Value.date", "Value.overview"}),
    #"Value.overview développé" = Table.ExpandRecordColumn(#"Value développé", "Value.overview", {"count", "opens", "openers", "shared", "os", "device", "read", "actives", "hasLinks", "clicks", "clickers"}, {"Value.overview.count", "Value.overview.opens", "Value.overview.openers", "Value.overview.shared", "Value.overview.os", "Value.overview.device", "Value.overview.read", "Value.overview.actives", "Value.overview.hasLinks", "Value.overview.clicks", "Value.overview.clickers"}),
    #"Value.overview.read développé" = Table.ExpandRecordColumn(#"Value.overview développé", "Value.overview.read", {"interest"}, {"Value.overview.read.interest"}),
    #"Value.overview.device développé" = Table.ExpandRecordColumn(#"Value.overview.read développé", "Value.overview.device", {"desktop"}, {"Value.overview.device.desktop"}),
    #"Value.overview.os développé" = Table.ExpandRecordColumn(#"Value.overview.device développé", "Value.overview.os", {"values"}, {"Value.overview.os.values"}),
    #"Value.overview.os.values développé" = Table.ExpandRecordColumn(#"Value.overview.os développé", "Value.overview.os.values", {"Windows"}, {"Value.overview.os.values.Windows"}),
    #"Colonnes supprimées" = Table.RemoveColumns(#"Value.overview.os.values développé",{"Value.overview.shared"})
in
    #"Colonnes supprimées"

votre "(Identifiant) => let
Source = () => let
Source = ....
in #"Colonnes supprimées"
In Source "
renvoie une fonction (non paramétrée) nommée Source

Cordialement
 

Statistiques des forums

Discussions
315 091
Messages
2 116 114
Membres
112 663
dernier inscrit
Pauline243