Self Service data ophalen vanuit Exact Online in Power BI ?>

Self Service data ophalen vanuit Exact Online in Power BI

Bij een ‘lokale’ installatie van Exact is het heel makkelijk om gegevens uit de database op te halen om verder te analyseren. Mijn collega Gertjan heeft hier al eens eerder over geblogd (zie http://blog.smartinsight.nu/correcte-auditfiles-genereren-uit-exact-globe/).

Als je gebruik maakt van Exact Online is dit minder recht toe recht aan. Exact Online werkt met een RESTfull API webservice (REST API) waarmee via het internet gegevens kunnen worden uitgelezen. De techniek rondom REST API’s bestaat al veel langer en hier is ook veel informatie over beschikbaar. Exact geeft ook zelf veel informatie op haar website beschikbaar over de mogelijke koppelingen (https://developers.exactonline.com/).

In onze projecten hebben wij de REST API van Exact Online al gebruikt. Hierbij maakten wij dan gebruik van SQL Server Integration Services in combinatie met C# scripts. Deze oplossing is vaak onderdeel van een grotere datawarehouse implementatie. Voor de gebruiker die ook ‘Self Service‘ gegevens uit Exact Online wil gebruiken voor analyses kan de REST API ook rechtstreeks in Power BI worden ingelezen. In deze blog laat ik zien welke stappen hiervoor moeten worden doorlopen.

Benodigdheden

Proces van authenticatie en autorisatie

Eén van de grootste uitdagingen bij het aanroepen van de REST API van Exact Online is het doorlopen van het proces van authenticatie en autorisatie. Exact Online maakt namelijk gebruik van de techniek OAUTH 2.0. Power BI ondersteunt deze techniek helaas (nog) niet vanuit de standaard functionaliteit.

OAUTH 2.0 maakt gebruik van tokens die worden uitgegeven nadat de klant met zijn inloggegevens is ingelogd in Exact Online.
Schematisch ziet dat er als volgt uit (op hoofdlijnen):

auth

Voor de uitwisseling van de gegevens is het niet nodig dat de inloggegevens elke keer moeten worden meegestuurd om de webservice aan te roepen. De toestemming die aan de app wordt gegeven is een jaar geldig. Na een jaar moet wederom toestemming gegeven worden.

Stappenplan

De volgende stappen zijn nodig om de gegevens vanuit de REST API in te kunnen lezen:

  1. Registratie van een app bij Exact Online
  2. Aanvragen access token via Postman
  3. Aanroepen van de API in Power BI

 

Registratie van een app bij Exact Online

Om de RESTfull API van ExactOnline te kunnen gebruiken moet je je eerst registreren als Developer in de App center van Exact Online. Deze registratie verloopt via https://www.exact.com/nl/exact-online/partners/app-center-partner.
Naast de mogelijkheid om de REST API’s te gebruiken, krijg je ook toegang tot een test administratie.

Nadat je een account hebt aangemaakt, kun je inloggen in de App Center via de link https://apps.exactonline.com/

Nadat je bent ingelogd, klik je bovenin op Registreer API Keys.

Klik op ‘Een nieuwe app toevoegen:

2

Voeg een App naam toe en vul als Redirect URL https://www.getpostman.com/oauth2/callback in.
Klik op Bewaren.

3

De App verschijnt nu in het overzicht.

4

Klik op Bewerken.

Onder het kopje Authenticatie vind je de Client ID en de ClientSecret.
Deze gegevens hebben we straks nodig, dus sla deze ergens op of houdt de website open.

5

Aanvragen access token via Postman

Zoals aangegeven ondersteunt Power BI standaard geen OAUTH 2.0 authenticatie flow. Daarom maken wij hier gebruik van Postman om deze authenticatie te regelen. De verleende toestemming is een jaar geldig, dus dan kunnen we in ieder geval even vooruit.

Open Postman en klik in het rechterscherm op Autorization:

6

Selecteer als Type OAuth 2.0.

Klik nu op Get New Access Token

7

Vul het pop-up scherm dat volgt in zoals in de afbeelding is aangegeven. Gebruikt als Client_id en Client_secret de gegevens van de app die in de eerste stap van deze blog is aangemaakt.

8

Als je kiest voor Request Token kom je in het volgende scherm van Exact Online.
9

 

Vul jouw inloggegevens voor Exact Online in. In het daarop volgende scherm geef je als gebruiker toestemming aan de App om verbinding te mogen maken met Exact Online.

Klik op Toestaan en je keert weer terug naar Postman.

Selecteer de zojuist aangemaakte Token ‘ExactOnline’.
Aan de rechterkant van het scherm zie je nu de gegevens van de token verschijnen.

10

De access_token is 600 seconden geldig. Daarna kan met behulp van een refresh_token een nieuw access_token worden opgevraagd.

Als je iets naar beneden scrolt zie je ook de gegevens van het refresh_token.

11
Deze token gaan we gebruiken in Power BI.

Aanroepen van de API in Power BI

Open Power BI desktop.

Kies in het lint op het tabblad Home voor Edit Queries

12

Kies in de Query Editor in het lint op tabblad Home nu voor Manage Parameters.

13

Maak via de knop New de volgende parameters aan:

14

Client_id  & Client_secret
Gebruik de gegevens voor het client-id en client_secret de gegevens die in stap 1 zijn aangemaakt.

URL
Vul hier de waarde https://start.exactonline.nl in.

Refresh_token
Als waarde voor de refresh_token moet de waarde van de refresh_token worden ingevuld die we in Stap 2 in Postman hebben opgevraagd.

URI

Exact Online kent vele verschillende resources die kunnen worden opgevraagd. Via de volgende link is de uitgebreide lijst terug te vinden: https://start.exactonline.nl/docs/HlpRestAPIResources.aspx?SourceAction=10

In deze blog gaan we een lijst met Grootboekrekeningen en Omschrijving ophalen. Vul als waarde bij de URI ‘financial/GLAccounts’ in.

DivisionCode

Power BI moet weten voor welke administratie de gegevens opgehaald moeten worden. Vul hier de DivisionCode vanuit Exact in.

Dit is overigens niet hetzelfde als het administratienummer in Exact Online.
Mocht je de DivisionCode niet weten ga dan naar Postman.

Vul achter GET de volgende URL in: https://start.exactonline.nl/api/v1/current/Me?$select=CurrentDivision

15

Vraag een nieuwe Access Token aan

16

Eventueel kun je de Access Token uit Stap 2 gebruiken, maar als deze verlopen is, kun je een nieuwe aanvragen.

Selecteer de Access Token en klik aan de rechterkant op Use Token.

17

Klik bovenin op de blauwe knop Send.

18

Onderin Postman krijg je nu het resultaat.

Tussen de tags CurrentDivision vind je de DivisionCode die je kunt gebruiken.

 19

Gegevens ophalen

Klik op OK en kies in het lint op het tabblad Home nu voor New Source en dan Blank Query.

20

Vul in het Advanced Editor scherm de volgende code in:


let

actualUrl =  URL & "/api/oauth2/token",

cntnt = Text.ToBinary(Uri.BuildQueryString(

[refresh_token= Refresh_token

,grant_type="refresh_token"

,client_id= Client_id

,client_secret=Client_secret

])),


options = [Headers =[#"Content-type"="application/x-www-form-urlencoded"],Content=cntnt],


result = Web.Contents(actualUrl, options),

#"JSON" = Json.Document(result),

access_token= #"JSON"[access_token],


AccessTokenHeader = "Bearer  " & access_token,

GetJsonQuery = (Web.Contents( URL & "/api/v1/"& Number.ToText(DivisionCode) & "/" & URI,

[Headers=[Authorization=AccessTokenHeader]])),

#"Imported XML" = Xml.Tables(GetJsonQuery,null,65001),

#"Changed Type" = Table.TransformColumnTypes(#"Imported XML",{{"id", type text}, {"updated", type datetime}}),

#"Expanded link" = Table.ExpandTableColumn(#"Changed Type", "link", {"Attribute:rel", "Attribute:title", "Attribute:href"},

{"link.Attribute:rel", "link.Attribute:title", "link.Attribute:href"}),

#"Expanded entry" = Table.ExpandTableColumn(#"Expanded link", "entry",

{"id", "title", "updated", "author", "link", "category", "content"}, {"entry.id", "entry.title", "entry.updated",

"entry.author", "entry.link", "entry.category", "entry.content"}),

#"Expanded entry.content" = Table.ExpandTableColumn(#"Expanded entry", "entry.content",

{"http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", "Attribute:type"},

{"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata", "entry.content.Attribute:type"}),

#"Removed Other Columns" = Table.SelectColumns(#"Expanded entry.content",{"link.Attribute:title",

"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"}),

#"Filtered Rows" = Table.SelectRows(#"Removed Other Columns", each ([#"link.Attribute:title"] = "GLAccounts")),

#"Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata" =

Table.ExpandTableColumn(#"Filtered Rows", "entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata",

{"properties"}, {"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties"}),

#"Removed Other Columns1" = Table.SelectColumns(#"Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata",

{"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties"}),

#"Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties" =

Table.ExpandTableColumn(#"Removed Other Columns1",

"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties", {"http://schemas.microsoft.com/ado/2007/08/dataservices"},

{"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices"}),

#"Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices"

= Table.ExpandTableColumn(#"Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties",

"entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices",

{"Code", "Description"}, {"Code", "Description"}),

#"Sorted Rows" = Table.Sort(#"Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.

http://schemas.microsoft.com/ado/2007/08/dataservices",{{"Code", Order.Ascending}})

in

#"Sorted Rows"

In hoofdlijnen doet deze code het volgende:

  • Deze code vraagt met behulp van de refresh_token een nieuw access_token aan;
  • Deze access_token wordt gebruikt in de aanroep van de API URL financials/GetAccounts;
  • Het laatste gedeelte van de code zet de response van de API om in een tabel en verwijderd de gegevens die we hier niet nodig hebben.

Het resultaat van deze code is dat er nu een tabel verschijnt met de grootboekrekeningen van de geselecteerde administratie:

21

Conclusie

Het gebruiken van de REST API van Exact Online in Power BI is niet geheel recht toe recht aan.  Met name het gedeelte rondom de authenticatie vraagt een aantal extra handelingen. Maar als één en ander eenmaal is ingericht, kun je je met behulp van de refresh_token jezelf in Power BI authentiseren.

Exact Online is een grote bron van gegevens waar zeker veel informatie uitgehaald kan worden met behulp van Power BI. Meer dan genoeg om uitgebreid te analyseren in ieder geval.

Succes!

Klik hier om naar onze site te gaan

73 gedachten over “Self Service data ophalen vanuit Exact Online in Power BI

  1. Hallo Gideon,

    Dank je wel voor het delen van deze geweldige blog.

    Ik heb hem nagespeeld, werkt prima. Ik kwam twee kleine dingen tegen die na knippen en plakken van het script niet direct werkten.

    de ‘ ‘ zitten in de weg en prefix ‘Bearer ‘ heeft een spatie nodig. Voor de rest prima. Scheelt mij een hele hoop uitzoekwerk.

    Hebben je misschien ook al onderzocht welke mogelijkheden er zijn om na het publishen van de PBIX het mogelijk is om de scheduled refresh in te stellen. Ik krijg de boodschap: “U kunt geen vernieuwing plannen voor deze gegevensset, omdat een of meer bronnen geen ondersteuning bieden voor vernieuwing.”

    Zou toch te gek zijn als dit ook nog zou werken,.

    Mijn M-script zoals het bij mij werkte:
    let
    actualUrl=URL&”/api/oauth2/token”,cntnt=Text.ToBinary(Uri.BuildQueryString([refresh_token=Refresh_token,grant_type=”refresh_token”,client_id=Client_id,client_secret=Client_secret])),
    options=[Headers=[#”Content-type”=”application/x-www-form-urlencoded”],Content=cntnt],
    result=Web.Contents(actualUrl,options),
    #”JSON”=Json.Document(result),
    access_token=#”JSON”[access_token],
    AccessTokenHeader=”Bearer ” & access_token,
    GetJsonQuery = (Web.Contents( URL & “/api/v1/”& Number.ToText(DivisionCode) & “/” & URI,[Headers=[Authorization=AccessTokenHeader]])),
    ImportedXML = Xml.Tables(GetJsonQuery,null,65001),
    #”Expandedlink”=Table.ExpandTableColumn(ImportedXML,”link”,{“Attribute:rel”,”Attribute:title”,”Attribute:href”},
    {“link.Attribute:rel”,”link.Attribute:title”,”link.Attribute:href”}),
    #”Expandedentry”=Table.ExpandTableColumn(#”Expandedlink”,”entry”,
    {“id”,”title”,”updated”,”author”,”link”,”category”,”content”},{“entry.id”,”entry.title”,”entry.updated”,
    “entry.author”,”entry.link”,”entry.category”,”entry.content”}),
    #”Expandedentry.content”=Table.ExpandTableColumn(#”Expandedentry”,”entry.content”,
    {“http://schemas.microsoft.com/ado/2007/08/dataservices/metadata”,”Attribute:type”},
    {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,”entry.content.Attribute:type”}),
    #”RemovedOtherColumns”=Table.SelectColumns(#”Expandedentry.content”,{“link.Attribute:title”,
    “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“}),
    #”FilteredRows”=Table.SelectRows(#”RemovedOtherColumns”,each([#”link.Attribute:title”]=”GLAccounts”)),
    #”Expandedentry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“=
    Table.ExpandTableColumn(#”FilteredRows”,”entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,
    {“properties”},{“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),
    #”RemovedOtherColumns1″=Table.SelectColumns(#”Expandedentry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,
    {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),
    #”Expandedentry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“=
    Table.ExpandTableColumn(#”RemovedOtherColumns1”,
    “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“,{“http://schemas.microsoft.com/ado/2007/08/dataservices”},
    {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“}),
    #”Expandedentry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices
    =Table.ExpandTableColumn(#”Expandedentry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“,
    “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,
    {“Code”,”Description”},{“Code”,”Description”})
    in
    #”Expandedentry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices

    1. Beste Wouter,
      Bedankt voor je reactie. Het blijkt dat de website de codes inderdaad een beetje vervormd. Mooi dat het toch gelukt is.

      Het reschedulen lukt waarschijnlijk niet door de web.contents functie. Power BI valideert de url die je meegeeft in deze functie en omdat de url zonder authenticatie nog niet werkt, gaat het mis.

      Dit kan je oplossen door de volgende aanpassingen te maken:

      ActualUrl vervangen door:
      actualUrl = URL

      En de options aan te passen naar:
      options = [RelativePath = “/api/oauth2/token”, Headers =[#”Content-type”=”application/x-www-form-urlencoded”],Content=cntnt],

      Dit zorgt ervoor dat de URL die gevalideerd wordt, goed gaat. Middels het toevoegen van het RelativePath in de options, gaat de functie alsnog naar de juiste url toe.

      Ik ben benieuwd of het hiermee lukt.

  2. Beste Gideon

    Bedankt voor deze post, alles werkt tot en met de query in PowerBI bij mij. Ik krijg de error ‘Token Identifier Expected’ bij de lijn  
    Weet u toevallig de oorzaak hiervan of weet u waar ik meer kan lezen over het opstellen van dergelijke queries? Alvast bedankt

    1. Beste Peter,

      In de code staat de code “& n b s p”. Deze kun je het beste helemaal verwijderen uit de code. Ik heb de code in de blog aangepast. Deze is het met kopieren er waarschijnlijk ten onrechte bij gekomen.

      De ‘taal’ waarin de querie geschreven is, is de Power Query Formula Language “M”. De officiele documentatie vind je via de volgende link: https://msdn.microsoft.com/library/mt211003.aspx

      Ik hoop dat je er zo uitkomt! Succes.

        1. Als het goed is, is dit niet nodig, maar misschien toch wel afhankelijk van de compjuter waar je op werkt.
          Wat je zou kunnen doen, is alle code na “[Headers=[Authorization=AccessTokenHeader]])) ” tot en met het woordje IN verwijderen en dan in jouw versie de stappen zelf volgen om de output te verwerken.
          Let op dat je ook de komma verwijderd na “[Headers=[Authorization=AccessTokenHeader]]))”

          1. Het is me uiteindelijk gelukt op een wat andere manier. Ik heb het Postman gedeelte & parameters achterwege gelaten en alles via Power BI gedaan. Bedankt!

  3. Beste Gideon, dank voor je uitleg – hiermee is het zelfs mij gelukt :-). Ik heb meer verstand van Finance dan van IT.
    Als ik het echter probeer toe te passen op “financialtransaction/TransactionLines”, krijg ik bij “GetJsonQuery” een foutmelding: “DataSource.Error: Web.Contents kan de inhoud niet ophalen van ‘https://start.exactonline.nl/api/v1/791095/financialtransaction/TransactionLines’ (400): Bad Request
    Details:
    DataSourceKind=Web
    DataSourcePath=https://start.exactonline.nl/api/v1/791095/financialtransaction/TransactionLines
    Url=https://start.exactonline.nl/api/v1/791095/financialtransaction/TransactionLines”
    Kun jij me verder helpen?

    1. Beste Ronald,
      Dit type foutmelding geeft aan dat de API de aanvraag niet goed kan verwerken, bijvoorbeeld omdat er tekens in staan die niet herkend worden.

      Er worden een paar variabelen ingevuld. Zou het kunnen dat daar ‘special characters’ in worden gebruikt? Zoals het & tekens of een ‘ ?

      1. Hoi Gideon,
        Dank voor je reactie. Om alles uit te sluiten heb ik nu het volgende gedaan:
        In PBI heb ik eerst in jouw werkende query de variabele “URI” vervangen door de harde waarde “financial/GLAccounts”. Dit werkte gewoon. Daarna heb ik in “Advanced Editor” de code van de query t/m de stap “GetJSonQuery” gekopieerd en in een nieuwe query (“GLAccounts”) geplakt. Het resultaat van deze query was: het xml-icoontje met als label “start.exactonline.nl” en het aantal bites; ook dit werkte dus. So far so good.
        Daarna heb ik in “Advanced Editor” in de query “GLAccounts” de harde waarde “financial/GLAccounts” vervangen door “financialtransaction/TransactionLines” en toen kwam een andere foutmelding: “kan niet verifiëren met de opgegeven referenties. Probeer het opnieuw.” Er is dus geen ander verschil dan bovenstaand en toch werkt het in ene niet meer. (Ik heb zelfs een compare in MSWord gedaan en dat leverde ook geen andere verschillen op).
        Het enige verschil is dus de benaderde tabel. Als ik kijk op de link uit je blog (https://start.exactonline.nl/docs/HlpRestAPIResources.aspx?SourceAction=10) dan zie ik dat
        – GLAccounts als supported methods “Get/Post/Put/Delete” heeft en geen webhook en
        – FinancialTransactions alleen “Get” en wel een webhook heeft
        Dit heeft er volgens mij (een leek) niets mee te maken.
        Ik weet niet hoe ik hiermee nu verder kom…
        Bijvoorbaat dank voor je feedback.

        1. …. overigens, na een refresh kwam de oude foutmelding weer naar voren:
          “DataSource.Error: Web.Contents kan de inhoud niet ophalen van ‘https://start.exactonline.nl/api/v1/791095/financialtransaction/TransactionLines’ (400): Bad Request
          Details:
          DataSourceKind=Web
          DataSourcePath=https://start.exactonline.nl/api/v1/791095/financialtransaction/TransactionLines
          Url=https://start.exactonline.nl/api/v1/791095/financialtransaction/TransactionLines”

        2. Hi Ronald,

          Dit zou nog met de data source settings te maken kunnen hebben. IN Edit Query editor kan je naar de data source settings kijken.
          Voor deze bron zal het Privacy level denk ik op Public moeten staan. Kun je dat checken?

          De query maakt inderdaad gebruik van de Get dus dat zou in dit geval niet uit moeten maken,

          1. Hoi Gideon,
            Als ik klik op “Start/Queries bewerken/Instellingen voor gegevensbron” krijg ik een pop-up “Onverwachte fout – De Objectverwijzing is niet op een exemplaar van het object ingesteld”. Er is hier dus duidelijk iets mis….
            Overigens heeft mijn GLAccounts versie 60 records. Ik ben er in geslaagd om voor sommige andere tabellen data naar voren te krijgen, maar in alle gevallen heb ik 60 records, niet meer, niet minder. Ik zei het net al: er is hier dus duidelijk iets mis…. 🙂

          2. Hi Ronald,
            Dit is inderdaad niet een hele leuke melding. En nogal vaag ook.
            Het zou kunnen dat dit te maken heeft met de versie van Power BI die je gebruikt. Welke versie gebruik je?
            Wellicht helpt het om Power BI te updaten naar de laatste versie

  4. Hoi Gideon,
    Bedankt voor jouw blog. Precies wat ik zocht. Ga dit graag eens uitproberen.
    Ik wil eerst ff testen met een demo omgeving van Exact. Stap 1 en 2 zijn gelukt. BIj het aanvragen van de request token wordt ik naar het login scherm van Exact. Online verwezen. Ik vul accountnaam en wachtwoord in maar dan krijg ik de volgende foutmelding: Oeps! Er is een fout opgetreden. Neem contact op….
    Met dezelfde gegevens kan ik wel inloggen bij Exact Online. Jij enig idee wat ik fout doe?
    Rob.

    1. Beste Rob,

      Vraag je de request token aan vanuit Postman?
      Je zou de redirect uri kunnen controleren die je bij Exact Online hebt opgegeven. Deze moet wel goed staan, anders weet exact online niet waar je naar teruggestuurd moet worden.

  5. Het is mij inmiddels gelukt om de request token aan te vragen na inloggen bij Excact met het inlogscherm dat jij ook beschrijft (ik kreeg eerst een algemeen inlogscherm).
    Ook mijn divisienummer is bekend, ik heb de parameters en de juiste refresh token ingevoerd.
    Bij het uitvoeren van het PowerBI Script moest ik bij de stap result mijn credentials opgeven. Ik heb daar gekozen voor Anonymous en kwam vervolgens door de stap heen. Nu krijg ik de vraag weer bij de stap GetJsonQuery. En kiezen voor Anonymous helpt niet. Ook niet als ik het laagste level kies.
    Enig idee wat er fout gaat? De Query zou toch zonder interactie moeten lopen?
    Alvast bedankt voor je hulp.
    Rob.

  6. Ik heb ‘m!
    Weet niet helemaal zeker wat het nu precies was, maar met dezelfde Anonymous credentials kom ik nu door alle stappen heen…..

    De laatste stap “Sorted Rows” leverde mij nog een foutmelding op:
    Expression.Error: The name ‘Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties. …. enz enz. Dezelfde melding van Peter eerder dus…

    Deze melding heb ik opgelost. In het script begint regel 90 net HTTP:// … Die regel moet echter direct aansluiten op de regel ervoor (harde return weggehaald).
    En dan gaat ‘ie goed….

  7. Hoi Gideon,
    Net als Ronald Kiebert wil ik een tweede tabel kunnen ontsluiten. Ik heb een tweede URI parameter aangemaakt en die verwezen naar: financial/GLSchemes.
    Vervolgensm, net als Ronald een nieuwe query gemaakt, kopie t./m stap
    #”Imported XML”….
    Om daarna de inhoud van het GL sschema op te halen e.d.

    Ook nu krijg ik helaas weer meldingen.
    Helaas ook bij de eerste query….
    “Expression.Error: The ‘Authorization’ header is only supported when connecting anonymously. These headers can be used with all authentication types: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Cache-Control, If-Modified-Since, Prefer, Referer”
    Wat ik nu ook probeer met de Data Source Settings, ik krijg het niet meer voor elkaar.

    Ik vermoed dat er iets niet goed gaat met de access_token. Die is niet als parameter aangemaakt, maar wordt wel gebruikt in he script (van af regel 25:

    access_token= #”JSON”[access_token],
    AccessTokenHeader = “Bearer ” & access_token,
    GetJsonQuery = (Web.Contents( URL & “/api/v1/”& Number.ToText(DivisionCode) & “/” & URI,
    [Headers=[Authorization=AccessTokenHeader]])),

    Waar haalt hij de access_code vandaan?
    NB: ik ben geen “echte” developper en dit is mijn eerste keer dat ik m.bv. een API (op Excact) data probeer op te halen. Ik doe mijn best, maar heb je hulp hier toch echt even nodig…
    Rob.

    1. Hi
      De access_token wordt opgehaald in de eerste 18 regels code. Met behulp van het refreshtoken wordt een nieuw access_token opgevraagd welke 600 seconde geldig is. Daarom wordt elke keer opnieuw het refreshtoken gebruikt in deze code.

      De melding die je krijgt: The ‘Authorization’ header is only supported when connecting anonymously. heeft wel te maken met de Data Source settings. Deze moet op Anonymous staan om het script anders niet werkt. Misschien helpt het om een nieuwe Power BI dashboard aan te maken en het e.e.a. opnieuw aan te maken. Soms onthoudt Power BI dingen die niet de bedoeling zijn…

  8. Hoi Gideon,

    Bedankt voor je uitleg. Ik blijf tegen de onderstaande foutmelding aan lopen :

    DataSource.Error: Web.Contents failed to get contents from ‘https://start.exactonline.nl/api/oauth2/token’ (400): Bad Request
    Details:
    DataSourceKind=Web
    DataSourcePath=https://start.exactonline.nl/api/oauth2/token
    Url=https://start.exactonline.nl/api/oauth2/token

    Ik heb je tips al uitgevoerd, opnieuw begonnen, een nieuwe token opgevraagd, maar de fout blijft komen.
    Heb jij nog wat tips?

    Alvast bedankt !!

    Groeten,
    Mark

    1. Hi Mark,

      Zou je een stukje van jouw code kunnen posten die je nu hebt ingevoerd in de Advanced Editor? Misschien dat ik daar iets aan kan zien.

      Je hebt via Postman wel een token kunnen opvragen?

      1. Hoi Gideon,

        Ik kan wel een token opvragen.

        Mijn code is:
        = let

        actualUrl = URL & “/api/oauth2/token”,

        cntnt = Text.ToBinary(Uri.BuildQueryString(

        [refresh_token= Refresh_token

        ,grant_type=”refresh_token”

        ,client_id= Client_id

        ,client_secret=Client_secret

        ])),

        options = [Headers =[#”Content-type”=”application/x-www-form-urlencoded”],Content=cntnt],

        result = Web.Contents(actualUrl, options),

        #”JSON” = Json.Document(result),

        access_token= #”JSON”[access_token],

        AccessTokenHeader = “Bearer ” & access_token,

        GetJsonQuery = (Web.Contents( URL & “/api/v1/”& Number.ToText(DivisionCode) & “/” & URI,

        [Headers=[Authorization=AccessTokenHeader]])),

        #”Imported XML” = Xml.Tables(GetJsonQuery,null,65001),

        #”Changed Type” = Table.TransformColumnTypes(#”Imported XML”,{{“id”, type text}, {“updated”, type datetime}}),

        #”Expanded link” = Table.ExpandTableColumn(#”Changed Type”, “link”, {“Attribute:rel”, “Attribute:title”, “Attribute:href”},

        {“link.Attribute:rel”, “link.Attribute:title”, “link.Attribute:href”}),

        #”Expanded entry” = Table.ExpandTableColumn(#”Expanded link”, “entry”,

        {“id”, “title”, “updated”, “author”, “link”, “category”, “content”}, {“entry.id”, “entry.title”, “entry.updated”,

        “entry.author”, “entry.link”, “entry.category”, “entry.content”}),

        #”Expanded entry.content” = Table.ExpandTableColumn(#”Expanded entry”, “entry.content”,

        {“http://schemas.microsoft.com/ado/2007/08/dataservices/metadata”, “Attribute:type”},

        {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“, “entry.content.Attribute:type”}),

        #”Removed Other Columns” = Table.SelectColumns(#”Expanded entry.content”,{“link.Attribute:title”,

        “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“}),

        #”Filtered Rows” = Table.SelectRows(#”Removed Other Columns”, each ([#”link.Attribute:title”] = “GLAccounts”)),

        #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata” =

        Table.ExpandTableColumn(#”Filtered Rows”, “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,

        {“properties”}, {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),

        #”Removed Other Columns1” = Table.SelectColumns(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,

        {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),

        #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties” =

        Table.ExpandTableColumn(#”Removed Other Columns1″,

        “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“, {“http://schemas.microsoft.com/ado/2007/08/dataservices”},

        {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“}),

        #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices

        = Table.ExpandTableColumn(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“,

        “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,

        {“Code”, “Description”}, {“Code”, “Description”}),

        #”Sorted Rows” = Table.Sort(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,{{“Code”, Order.Ascending}})

        in

        #”Sorted Rows”

        Kun je daar wat mee?

        Alvaste bedankt!!

        Groeten,

        Mark

  9. Hi Gideon,

    Een token opvragen lukt (ik heb er nu ook meerdere).
    Dit heb ik nu als code staan:
    = let

    actualUrl = URL & “/api/oauth2/token”,

    cntnt = Text.ToBinary(Uri.BuildQueryString(

    [refresh_token= Refresh_token

    ,grant_type=”refresh_token”

    ,client_id= Client_id

    ,client_secret=Client_secret

    ])),

    options = [Headers =[#”Content-type”=”application/x-www-form-urlencoded”],Content=cntnt],

    result = Web.Contents(actualUrl, options),

    #”JSON” = Json.Document(result),

    access_token= #”JSON”[access_token],

    AccessTokenHeader = “Bearer ” & access_token,

    GetJsonQuery = (Web.Contents( URL & “/api/v1/”& Number.ToText(DivisionCode) & “/” & URI,

    [Headers=[Authorization=AccessTokenHeader]])),

    #”Imported XML” = Xml.Tables(GetJsonQuery,null,65001),

    #”Changed Type” = Table.TransformColumnTypes(#”Imported XML”,{{“id”, type text}, {“updated”, type datetime}}),

    #”Expanded link” = Table.ExpandTableColumn(#”Changed Type”, “link”, {“Attribute:rel”, “Attribute:title”, “Attribute:href”},

    {“link.Attribute:rel”, “link.Attribute:title”, “link.Attribute:href”}),

    #”Expanded entry” = Table.ExpandTableColumn(#”Expanded link”, “entry”,

    {“id”, “title”, “updated”, “author”, “link”, “category”, “content”}, {“entry.id”, “entry.title”, “entry.updated”,

    “entry.author”, “entry.link”, “entry.category”, “entry.content”}),

    #”Expanded entry.content” = Table.ExpandTableColumn(#”Expanded entry”, “entry.content”,

    {“http://schemas.microsoft.com/ado/2007/08/dataservices/metadata”, “Attribute:type”},

    {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“, “entry.content.Attribute:type”}),

    #”Removed Other Columns” = Table.SelectColumns(#”Expanded entry.content”,{“link.Attribute:title”,

    “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“}),

    #”Filtered Rows” = Table.SelectRows(#”Removed Other Columns”, each ([#”link.Attribute:title”] = “GLAccounts”)),

    #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata” =

    Table.ExpandTableColumn(#”Filtered Rows”, “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,

    {“properties”}, {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),

    #”Removed Other Columns1” = Table.SelectColumns(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,

    {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),

    #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties” =

    Table.ExpandTableColumn(#”Removed Other Columns1″,

    “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“, {“http://schemas.microsoft.com/ado/2007/08/dataservices”},

    {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“}),

    #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices

    = Table.ExpandTableColumn(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“,

    “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,

    {“Code”, “Description”}, {“Code”, “Description”}),

    #”Sorted Rows” = Table.Sort(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,{{“Code”, Order.Ascending}})

    in

    #”Sorted Rows”

    Ik hoop dat je er wat mee kunt.

    Groeten,

    Mark

    1. Hi,

      Als je in de Advanced Editor zit, krijg je dan een melding linksonderin.
      In de engelse versie kan er staan ‘Token literal expected’ Show error.

      Of staat er No syntax errors detected?

      In de code die jij hebt geplakt staat voor het woordje LET namelijk een = teken. en die moet iig weg volgens mij

  10. Hi Gideon,

    Op het moment dat ik het ‘=’weg laat, dan worden in de query “” en #LF getoond, zie onder

    let#(lf) #(lf)actualUrl = URL & “”/api/oauth2/token””,#(lf) #(lf)cntnt = Text.ToBinary(Uri.BuildQueryString(#(lf) #(lf)[refresh_token= Refresh_token#(lf) #(lf),grant_type=””refresh_token””#(lf) #(lf),client_id= Client_id#(lf) #(lf),client_secret=Client_secret#(lf) #(lf)])),#(lf) #(lf) #(lf)options = [Headers =[#””

    Linksonderaan komt de melding ‘Ready’

    1. Hi

      Die #(lf) is een spcial character, maar zou niet in de advanced editor naar voren moeten komen. Welicht dat er met het kopieren van de code ook een stukje opmaakt mee gekopieerd is.

      Heb je al geprobeerd om de code nog een keer te opnieuw in te voeren. Wellicht eerst plakken in kladblok en dan pas in power bi? Of ‘overtypen’.

      Zitten er anders in de client_secret of client_id nog special characters? Aanhalingstekens of slashes of iets dergelijks?

  11. Beste Gideon,

    In twee andere berichten zag ik dat je ook ervaring hebt met het ophalen van data uit AFAS via de GetConnector.

    Volgens mij moet het mogelijk zijn om op een vergelijkbare manier zoals hierboven met Power BI en de functie Web.Contents direct gegevens te importeren van een AFAS web services GetConnector maar ik krijg het (nog) niet voor elkaar…

    Heb jij misschien een voorbeeld van de daarvoor benodigde M code?

    Alvast bedankt!

    Groeten,

    Martijn

    1. Beste Martijn,

      AFAS rechtstreeks naar Power BI heb ik nog niet eerder gedaan, maar zou iid wel moeten lukken.

      Ik zal er eens naar kijken. Misschien mooie aanleiding voor een nieuwe blog 🙂

      1. Bedankt voor de snelle reactie. Goed om te horen dat het in ieder geval mogelijk moet zijn. Mocht je een voorbeeld kunnen produceren dan hoor ik het natuurlijk graag 🙂

          1. Super! Ik was ook al weer wat verder maar met jouw uitleg erbij komt het zeker goed. Bedankt! 🙂

  12. Hallo Gideon,

    vooreerst bedankt om dit artikel te delen!

    Heb een vraag tijdens de laatste stap gegevens ophalen.
    Momenteel krijg ik eerst de melding:
    ‘please specify how to connect’: via edit credentials kom ik in het access web content scherm.
    Hier kies ik voor anonymous en geef ik als “select which level to apply these settings to” het volgende in: “https://start.exactonline.be/”
    Wanneer ik klik op connect krijg ik volgende melding:
    “Information is required about data privacy”: Ik krijg het privacy levels scherm te zien waar ik moet aanduiden of de url https://start.exactonline.be/ Public, Organizational of Private is.
    Heb alle combinaties geprobeerd maar krijg telkens de melding “we couldn’t authenticate with the credentials provided. Please try again”.

    Enig idee? Client id, secret en refresh token meermaals gecontroleerd maar hier is alles correct meegegeven.

    Alvast bedankt voor uw antwoord.
    Vriendelijke groet,
    Koen

    1. Beste Koen,

      De melding lijkt toch aan te geven dat er met de combinatie van inloggegevens iets niet goed gaat.
      Heb je via Postman ook geprobeerd connectie te maken? Krijg je dan wel resultaten?

      Zou het misschien nog kunnen dat in de refreshtoken ‘speciale characters’ voorkomen zoals haakjes of its dergelijks? Daar kan het namelijk nog misgaan.

      1. Beste Gideon,

        bedankt voor de postman tip. Via postman werkte alles perfect, heb dan veder gekeken naar het advanced script en zag dat er 2 spaties aanwezig waren bij het doorgeven van de AccessTokenHeader. door een spatie weg te doen is het gelukt!

        Bedankt,
        Vriendelijke groeten,
        Koen

  13. Dag Gideon,

    Dank voor het delen van deze kennis.
    Mijn query loopt momenteel vast met de volgende melding:
    Expression.Error: De veldnaam Authorization wordt alleen ondersteund bij een anonieme verbinding. Deze veldnamen kunnen met alle authenticatietypen worden gebruikt: Accept, Accept-Charset, Accept-Encoding, Accept-Language, Cache-Control, If-Modified-Since, Prefer, Referer

    Deze bevinst zich in de GetJsonQuery. De instellingen voor de gegevensbron (https://start.exactonline.nl/api/oauth2/token) staat echter ingesteld op anoniem.

    Dank alvast voor je hulp!

    1. ik las de oplossing al, nu echter deze melding:

      DataSource.Error: Web.Contents failed to get contents from ‘https://start.exactonline.nl/api/oauth2/token/api/oauth2/token’ (404): Not Found
      Details:
      DataSourceKind=Web
      DataSourcePath=https://start.exactonline.nl/api/oauth2/token/api/oauth2/token
      Url=https://start.exactonline.nl/api/oauth2/token/api/oauth2/token

      zie dat api/oauth2 dubbel staat… maar zie niet waar het mis is in de code:
      let

      actualUrl = URL & “/api/oauth2/token”,

      cntnt = Text.ToBinary(Uri.BuildQueryString(

      [refresh_token= Refresh_token

      ,grant_type=”refresh_token”

      ,client_id= Client_id

      ,client_secret=Client_secret

      ])),

      options = [RelativePath = “/api/oauth2/token”, Headers =[#”Content-type”=”application/x-www-form-urlencoded”],Content=cntnt],

      result = Web.Contents(actualUrl, options),

      #”JSON” = Json.Document(result),

      access_token= #”JSON”[access_token],

      AccessTokenHeader = “Bearer ” & access_token,

      GetJsonQuery = (Web.Contents( URL & “/api/v1/”& Number.ToText(DivisionCode) & “/” & URI,

      [Headers=[Authorization=AccessTokenHeader]])),

      #”Imported XML” = Xml.Tables(GetJsonQuery,null,65001),

      #”Changed Type” = Table.TransformColumnTypes(#”Imported XML”,{{“id”, type text}, {“updated”, type datetime}}),

      #”Expanded link” = Table.ExpandTableColumn(#”Changed Type”, “link”, {“Attribute:rel”, “Attribute:title”, “Attribute:href”},

      {“link.Attribute:rel”, “link.Attribute:title”, “link.Attribute:href”}),

      #”Expanded entry” = Table.ExpandTableColumn(#”Expanded link”, “entry”,

      {“id”, “title”, “updated”, “author”, “link”, “category”, “content”}, {“entry.id”, “entry.title”, “entry.updated”,

      “entry.author”, “entry.link”, “entry.category”, “entry.content”}),

      #”Expanded entry.content” = Table.ExpandTableColumn(#”Expanded entry”, “entry.content”,

      {“http://schemas.microsoft.com/ado/2007/08/dataservices/metadata”, “Attribute:type”},

      {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“, “entry.content.Attribute:type”}),

      #”Removed Other Columns” = Table.SelectColumns(#”Expanded entry.content”,{“link.Attribute:title”,

      “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“}),

      #”Filtered Rows” = Table.SelectRows(#”Removed Other Columns”, each ([#”link.Attribute:title”] = “GLAccounts”)),

      #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata” =

      Table.ExpandTableColumn(#”Filtered Rows”, “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,

      {“properties”}, {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),

      #”Removed Other Columns1” = Table.SelectColumns(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata“,

      {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“}),

      #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties” =

      Table.ExpandTableColumn(#”Removed Other Columns1″,

      “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“, {“http://schemas.microsoft.com/ado/2007/08/dataservices”},

      {“entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“}),

      #”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices

      = Table.ExpandTableColumn(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties“,

      “entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,

      {“Code”, “Description”}, {“Code”, “Description”}),

      #”Sorted Rows” = Table.Sort(#”Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.http://schemas.microsoft.com/ado/2007/08/dataservices“,{{“Code”, Order.Ascending}})

      in

      #”Sorted Rows”

  14. Hallo Gideon,

    Exact geeft aan dat er een limiet is van 60 records per API request >> https://developers.exactonline.com/#REST Restrictions.html

    Ik vermoed dat dit de oorzaak is van het feit dat ik maar 60 rijen GL accounts te zien krijg in Power BI met jouw script (net als Ronald Kiebert hierboven). Is deze aanname juist volgens jou? En zo ja, heb je enig idee hoe / of ik deze limiet kan verhogen met een aanpassing van het script?

  15. Beste Sander,
    De cdocumentatie geeft aan dat op de meeste READ request geen limiet zit, maar het lijkt er wel op dat dit het probleem is als je maar 60 records ziet.
    Dit is op te lossen door een nieuwe request te doen en gebruik te maken van de skiptoken.
    Hiervoor moet het script wel uitgebreid worden.

        1. Beste Valentijn,

          Ik heb hier nog niet verder naar gekeken..
          Maar je zou neen soort van loop moeten maken en op basis van de skip token bepalen of je verder moet gaan.

  16. Hoi Gideon,

    Met bovenstaande reacties al een paar foutmeldingen weten op te lossen. De volgende staat er alleen helaas nog niet tussen:

    — Formula.Firewall: Query ‘Query1’ (step ‘Sorted Rows’) is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination. —

    Enig idee waar dit aan kan liggen?

    Alvast bedankt.

    1. Hi Michael,
      De privacy levels van een data source kan je instellen via Home, Pijltje naast Edit Queries, Data source settings.
      Els je vervolgens op Edit settings klikt, zie je het Privacy Level staan.
      Blijkbaar zjn er meerdere data sources die verschillende privacy levels hebben.
      Als je deze opnieuw instelt (ik denk op None) dan moet het volgens mij goed komen.

  17. Hallo,
    Misschien een beetje rare vraag maar ik zie het “Apps beheren” linkje niet om op te klikken terwijl ik wel een App Development account heb. We hebben al eens eerder een integratie gemaakt met FreshDesk namelijk. Heb je hiervoor iet speciaals nodig?

    1. Hi Eric,

      Ik heb even gekeken maar ik zie dat het tegenwoordig Registreer API Keys heet in plaats van Apps beheren.
      De vervolg stappen lijken nog wel hetzelfde.

      1. Hi Gideon,
        Bedankt voor he reactie. Er blijkt wel meer anders te zijn. Ik kan ook geen test app registreren. Ik moet een productie app registreren en daar moet ik voor betalen. Ik zou dit wel graag eerst willen testen. Ik heb al bij Exact een support vraag hierover gesteld. Het is mij nog niet gelukt om dit op jou manier werkend te krijgen.

  18. Hartelijk dank voor het delen van deze informatie: Ik krijg echter nog de volgende foutmelding:

    Expression.Error: The column ‘id’ of the table wasn’t found.
    Details:
    id

    Nu vraag ik mij af wat doe ik fout?

    1. Beste Gerben,

      Haal je ook de Grootboekrekeningen ook (financial/GLAccounts)? Elk endpoint van de API heeft zijn eigen kolommen.
      Deze kun je hier vinden: https://start.exactonline.nl/docs/HlpRestAPIResources.aspx?SourceAction=10

      In bovenstaande code onder Gegevens ophalen zie je rond regel 42 staan welke kolommen verwacht worden:

      #”Expanded entry” = Table.ExpandTableColumn(#”Expanded link”, “entry”,

      {“id”, “title”, “updated”, “author”, “link”, “category”, “content”}, {“entry.id”, “entry.title”, “entry.updated”,
      “entry.author”, “entry.link”, “entry.category”, “entry.content”})

      Misschien heeft het endpoint dat jij gebruikt geen ID?

  19. Hoi Gideon, bedankt voor dit leuke stuk.

    Op dit moment loop ik vast op: Formula.Firewall: Query ‘Query1’ (step ‘Custom1′) is accessing data sources that have privacy levels which cannot be used together. Please rebuild this data combination.

    Als ik de datasource settings – permissions wijzig (Anonymous, None) of andere combi’s helpt dat niet. Heb jij nog een tip?

    Bvd Sjoerd

    1. Beste Sjoerd,

      Dit is idd een vervelende melding die niet altijd goed te traceren is.
      Kan het zijn dat je twee queries met elkaar probeert te verbinden via bijvoorbeeld een merge? Dan kan het helpen om deze dataverbinding een keer helemaal opnieuw aan te maken?

      Wellicht lees je ook nog een excel bestand of zo in? Deze combinatie loopt wel vaker mis.

      Als je de Applied steps per stuk doorloopt, dan kun je achterhalen bij welke stap hij precies misloopt. Misschien dat je het dan kan achterhalen.

  20. Ik krijg de onderstaande melding, iemand een idee?

    An error occurred in the ‘’ query. Expression.Error: The name ‘Sorted Rows’ wasn’t recognized. Make sure it’s spelled correctly.

    1. Hi Brian,

      Dat lijkt in 1 van de laatst regels te zitten.
      Als je in de Advanced editor kijkt, zie je dan een foutmelding (links onderin)?

      Anders kan je wellicht onder de Applied steps in de Query editor de stap Sorted rows verwijderen.

      1. Hi Gideon,

        Nee in de Advanced editor krijg ik netjes No syntax errors have been detected.

        Als ik jouw code erin plakt dat krijg ik onderstaande error
        Expression.Error: The name ‘Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.

        http://schemas.microsoft.com/ado/2007/08/dataservices‘ wasn’t recognized. Make sure it’s spelled correctly.

        Als ik vervolgens de na [Headers=[Authorization=AccessTokenHeader]])) alles weghaalt tot in krijg ik de melding welke ik eerder aangaf over die Sorted rows.

        Groet, Brian

        1. De Expanded entry content lijkt te verwijzen naar een stukje code die nog na de AccessTokenHeader staat.
          Heb je dit staan:

          let

          actualUrl = URL & “/api/oauth2/token”,

          cntnt = Text.ToBinary(Uri.BuildQueryString(

          [refresh_token= Refresh_token

          ,grant_type=”refresh_token”

          ,client_id= Client_id

          ,client_secret=Client_secret

          ])),

          options = [Headers =[#”Content-type”=”application/x-www-form-urlencoded”],Content=cntnt],

          result = Web.Contents(actualUrl, options),

          #”JSON” = Json.Document(result),

          access_token= #”JSON”[access_token],

          AccessTokenHeader = “Bearer ” & access_token,

          GetJsonQuery = (Web.Contents( URL & “/api/v1/”& Number.ToText(DivisionCode) & “/” & URI,

          [Headers=[Authorization=AccessTokenHeader]]))

          in

          GetJsonQuery

  21. In mijn Exact online heb ik meerdere administratie. Als ik gegevens op wil halen zal ik ergens moeten aangeven uit welke administratie ik deze wil halen. Op dit moment ben ik zover dat ik geen foutmeldingen meer krijg maar ik krijg ook geen data te zien.
    Via Postman heb ik de DivisionCode opgehaald, maar hier kan ik nergens iets vinden om te bepalen om welke administratie het gaat.
    Iemand een idee hoe dit in te stellen is?

    1. Hoi Danielle,

      De Division Code die je hebt opgehaald, is de identificatie van de administratie.
      Als je deze invult bij de parameters wordt deze division code gebruikt bij het ophalen van de gegevens.

      1. Hoi Gideon,

        Bedankt voor je snelle reactie. Maar als ik in Postman de stappen doorloop voor de Request Token kom ik in het inlogscherm van Exact Online. De gegevens (inlognaam en wachtwoord) die ik hier invul geven toegang tot een aantal administraties. Ik zou toch ergens moeten bepalen voor welke administratie ik gegevens wil ophalen.
        Na het doorlopen van alle stappen en het invullen van de code krijg ik geen foutmelding maar ik krijg ook geen gegevens. Ik zie 1 kolom met 1 rij met daarin de tekst “Sorted Rows”

        1. Hoi Danielle,
          Als je inlogt in Exact Online zelf en daar van admiistratie wisselt zie je in de URL ook de divisioncode staan van de administratie waar je dan in zit.
          Helpt dat?

          1. Hoi Gideon,

            Ik heb de divisioncode inderdaad gevonden. Ik krijg nu alleen de melding “Kan niet verifiëren met de opgegeven referentie. Probeer het opnieuw.”
            Bij instellingen voor gegevensbron -> machtigingen bewerken heb ik inmiddels alle combinaties al gehad.

          2. Hi Danielle

            Dat is wel vreemd.
            Heb je wellicht al geprobeerd om de API aan te roepen in Postman? Het kan zijn dat je daar dan nog een specifiekere foutmelding krijgt die je kan helpen om dit op te lossen.

  22. Dag Gideon,

    Alvast bedankt voor deze blog!
    Ik loop helaas vast bij het opvragen van de tokens.
    Ik kan inloggen maar wanneer ik dan toegang geef aan Postman tot mijn Exact Online account krijg ik dit: Could not complete 0Auth 2.0 login. Check Postman Console for more details.
    Request Headers:
    content-type:”application/x-www-form-urlencoded”
    authorization:”Basic NGU3NzAwY2YtNjAxMy00N2IyLWE0YzMtYzNlMzdlZjQyYTNkOmpqVEg3TWZKekhRaQ==”
    user-agent:”PostmanRuntime/7.1.5″
    accept:”*/*”
    host:”start.exactonline.be”
    accept-encoding:”gzip, deflate”
    content-length:551
    Request Body:
    grant_type:”authorization_code”
    code:”F-jE!IAAAACoOXXVW4yNPc7m3OE1xkneODpdlsNTbL66CnMj39zu-AQEAAAFMXxE4yFA8zpwMYLgv9e7gdcqVVj3mh4k2Sx3OPSRYjDNWPA0eYYnvA1kL6jwO4FFZGoCZ2qdbAY5OQZJnI51wF6c28bMPyNytbiQ9VlpQfKUAshKSRHL-l6idyZ5CqeG-08_jARw0NWxSsWSgrTRPQ60RztUR_TI_5wKtFtkutwYMx8OX1cZI4zv2nzD9pWlZH2nMBUidodQMiIfxkX4ekOlgpeXfWNZWyHuww3pADTAx1I0qAiVI51k95MLioWEmVmql_IN1ZC_fdmiy7qRII1u8Y2Peh5nt42VzcRelR2NuvEDUcRGmzKdOmZ0mibjGBDs7zf6J4OIrya7euGxS”
    redirect_uri:”https://www.getpostman.com/oauth2/callback”
    client_id:”4e7700cf-6013-47b2-a4c3-c3e37ef42a3d”
    Response Headers:
    content-type:”application/json; charset=utf-8″
    content-length:”27″
    cache-control:”no-cache, no-store”
    pragma:”no-cache”
    expires:”-1″
    x-xss-protection:”1; mode=block”
    x-content-type-options:”nosniff”
    referrer-policy:”origin-when-cross-origin”
    date:”Thu, 31 May 2018 14:23:31 GMT”
    connection:”close”
    set-cookie:
    0:”ExactServer{f052a90d-256f-48b1-98b2-e16f967d9545}=Division=1; path=/; secure; HttpOnly; SameSite=lax”
    1:”ExactOnlineClient=8fb1AL4aqvm9A+DsBoc5AkaZ/7zrg/BblfI2ibOQj2rYGYXzuXMlpmI9vlUpbe7ZBcyWMc/inpDii/BeUPvyTh2XUkgGgStAWm23EXvNQD9HP/YRnuYxQMdzWRNDJuIN++n33N3sdzfIhA0LM2jGqHaFTeiaYFUZk1u24UsN+wU=; expires=Mon, 31-Dec-2198 23:00:00 GMT; path=/; secure; HttpOnly; SameSite=lax”
    2:”dtCookie=1$358135B48E0B7FD2DD9344373CA62D69; Path=/; Domain=.dynatrace.com”
    access-control-allow-credentials:”true”
    access-control-allow-headers:”*”
    access-control-allow-methods:”GET,POST,PUT,DELETE,OPTIONS,HEAD”
    access-control-allow-origin:”*”
    strict-transport-security:”max-age=31536000; includeSubDomains”
    Response Body:
    error:”invalid_request”

    Enig idee wat ik kan doen?

    Alvast bedankt!

    Arne

      1. Hi Arne,

        Interessante foutmelding.
        Ik kan niet precies zien waar het probleem inzit.
        Het is nog bij het opvragen van een token toch?
        Ik kan 2 dingen bedenken:
        – heb je de callback url bij Exact van Postman ingegeven?
        – kloppen de instellingen bij het opvargen van de token? Zie ik goed dat je probeert in te loggen bij Exact Online be? Dan moet je ook de URL’s aanpassen voor het opvragen van de tokens (geen .nl, maar .be) volgens mij

  23. Beste Gideon,

    Ik heb je stappen gevold en tot aan alle stappen in Postman gaat alles prima. Echter na het aanmaken van de parameters in PowerBI en het invoeren van de code om gegevens ophalen krijg ik een fout.

    Namelijk de volgende melding:
    *********************************************
    Expression.Error: The name ‘Expanded entry.content.http://schemas.microsoft.com/ado/2007/08/dataservices/metadata.properties.

    http://schemas.microsoft.com/ado/2007/08/dataservices‘ wasn’t recognized. Make sure it’s spelled correctly.
    *********************************************

    Enig idee wat ik fout doen?

    1. Beste Joep,

      Wat er precies fout gaat is moeilijk te zeggen met alleen deze melding.
      Het lijkt er op dat er misschien ergens iets met de haakjes of aanhalingstekens niet goed gaat.
      De melding geeft aan dat er gezocht wordt naar een bepaald naam die hij niet kan vinden. De naam die hij niet kan vinden stata rond regels 48 in het code blok en vanaf regel 54 wordt deze naam weer gebruikt.
      Als je in de Advanced editor zit, zie je dan misschien links onderin een melding dat er nog een fout in de code zit? Vanaf daar kan je dan ook door klikken naar de plek wara de code zit, misschien dat je daar het probleem kan vinden?

Geef een reactie

Het e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *