Power BI rapport Exact Online Productie rapport duurt 2 uur om te verversen

Bijgevoegd Power BI rapport voor een relatief kleine Exact Online productie administratie doet er 2:00 tot 2:15 om te verversen.

Dat is sowieso onhandig vanwege de maximale refresh-time van 2:00 uur voor een Power BI Pro-licentie (in de cloud).

Hoe kan ik dit dashboard versnellen?

Bijgevoegd Power BI-template voor Exact Online productie en voorbeeld Excel-bestand met prognoses.

Exact Online Manufacturing.pbit (225,0 KB)

Prognose3.xlsx (14,1 KB)

De prestaties van dit rapport zijn goed te verbeteren, op onderdelen zelfs tot 100x sneller zonder aanpassingen aan de Exact Online database die de connector beschikbaar stelt.

Een generieke verbetering is om op een paar resterende Exact tabellen zoals GLAccountClassificationMappings ook nog de parameter “URL Invantive” te gebruiken zoals beschreven op Use Power BI parameters with Invantive Bridge Online ; dat maakt het Power BI rapport gemakkelijker te analyseren en verbeteren. Maar het grootste gebruikt al netjes een Power BI parameter.

De grootste stap qua snelheidswinst is om over te stappen naar andere Exact tabellen van de connector; van de volgende tabellen is de langzaamste variant in gebruik, terwijl de nieuwe varianten tot wel 100x sneller zijn:

Lees ook de tips voor het gebruik van de Exact Online *Incremental tabellen in Power BI op Snel en met minder API-calls Exact Online uitlezen met de incrementele "sync API"-tabellen en daaraan gekoppelde uitleg. Merk ook op dat indien gefiltered wordt op Exact Online administratie in Power BI binnen talrijke actieve administratise, dat hiervoor veel optimalisaties automatisch afgaan zodat het mogelijk blijft om real-time cijfers uit Exact Online in Power BI in te lezen.

De tabel Transactions kan vervangen worden door te zoeken naar regel 0 (de kopregel) in TransactionLinesIncremental. Deze wordt toch al opgehaald.

Helaas is er nog geen mooie oplossing voor het sneller ophalen van de MfgTimeTransactions. Deze tabel bevat alle gemaakte uren in productie. Het is het overwegen waard om te werken met filters, zoals op datum. Dit beperkt het volume enorm en verhoogt de snelheid pro-rato.

Er kunnen goede redenen zijn om de langzaamste variant van de Exact Online tabellen te gebruiken van bijvoorbeeld SalesOrderLines. Ze bieden veel betere filtermogelijkheden op bijvoorbeeld open orders alhoewel de nieuwe mandatory filtering daar weer afbreuk aan doet. Mandatory filtering wordt trouwens automatisch voor gecorrigeerd op Exact Online; je hoeft hiermee in Microsoft Power BI geen rekening te houden.

Als structurele verbetering wordt overwogen om indien via een langzame tabel veel data opgehaald wordt automatisch een tuningadvies per e-mail te geven.

Verkeerde Cardinaliteit GLTransactions

In de volgende query op GLTransactions zit een foutje:

let
//    Bron = Odbc.DataSource("dsn=CData ExactOnline Sys", [HierarchicalNavigation=true]),
//    CData_Database = Bron{[Name="CData",Kind="Database"]}[Data],
//    ExactOnline_Schema = CData_Database{[Name="ExactOnline",Kind="Schema"]}[Data],
    Bron = OData.Feed(#"URL Invantive", null, [Implementation="2.0"]),
//    GLAccounts_Table = ExactOnline_Schema{[Name="GLAccounts",Kind="Table"]}[Data],
    GLAccounts_Table = Bron{[Name="ExactOnlineREST.Financial.GLAccountsBulk@eol",Signature="table"]}[Data],
    #"Query's samengevoegd" = Table.NestedJoin(GLAccounts_Table, {"ID"}, ItemGroups, {"GLCosts"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen" = Table.ExpandTableColumn(#"Query's samengevoegd", "ItemGroups", {"ID", "GLCosts"}, {"ItemGroups.ID", "ItemGroups.GLCosts"}),
    #"Query's samengevoegd1" = Table.NestedJoin(#"ItemGroups uitgevouwen", {"ID"}, ItemGroups, {"GLPurchaseAccount"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen1" = Table.ExpandTableColumn(#"Query's samengevoegd1", "ItemGroups", {"ID", "GLPurchaseAccount"}, {"ItemGroups.ID.1", "ItemGroups.GLPurchaseAccount"}),
    #"Query's samengevoegd2" = Table.NestedJoin(#"ItemGroups uitgevouwen1", {"ID"}, ItemGroups, {"GLPurchasePriceDifference"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen2" = Table.ExpandTableColumn(#"Query's samengevoegd2", "ItemGroups", {"ID", "GLPurchasePriceDifference"}, {"ItemGroups.ID.2", "ItemGroups.GLPurchasePriceDifference"}),
    #"Query's samengevoegd3" = Table.NestedJoin(#"ItemGroups uitgevouwen2", {"ID"}, ItemGroups, {"GLRevenue"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen3" = Table.ExpandTableColumn(#"Query's samengevoegd3", "ItemGroups", {"ID", "GLRevenue"}, {"ItemGroups.ID.3", "ItemGroups.GLRevenue"}),
    #"Filtered Rows" = Table.SelectRows(#"ItemGroups uitgevouwen3", each ([ID] = "45dbb5ee-00d0-4102-955a-7c1b1e2fd9c6")),
    #"Query's samengevoegd4" = Table.NestedJoin(#"Filtered Rows", {"ID"}, ItemGroups, {"GLStock"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen4" = Table.ExpandTableColumn(#"Query's samengevoegd4", "ItemGroups", {"ID", "GLStock"}, {"ItemGroups.ID.4", "ItemGroups.GLStock"}),
    #"Query's samengevoegd5" = Table.NestedJoin(#"ItemGroups uitgevouwen4", {"ID"}, ItemGroups, {"GLStockVariance"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen5" = Table.ExpandTableColumn(#"Query's samengevoegd5", "ItemGroups", {"ID", "GLStockVariance"}, {"ItemGroups.ID.5", "ItemGroups.GLStockVariance"}),
    #"Aangepaste kolom toegevoegd" = Table.AddColumn(#"ItemGroups uitgevouwen5", "Itemgroup_ID", each if [ItemGroups.GLCosts] <> null then [ItemGroups.ID] else if [ItemGroups.GLPurchaseAccount] <> null then [ItemGroups.ID.1] else if [ItemGroups.GLPurchasePriceDifference] <> null then [ItemGroups.ID.2] else if [ItemGroups.GLRevenue] <> null then [ItemGroups.ID.3] else if [ItemGroups.GLStock] <> null then [ItemGroups.ID.4] else if [ItemGroups.GLStockVariance] <> null then [ItemGroups.ID.5] else null),
    #"Query's samengevoegd6" = Table.NestedJoin(#"Aangepaste kolom toegevoegd", {"Itemgroup_ID"}, ItemGroups, {"ID"}, "ItemGroups", JoinKind.LeftOuter),
    #"ItemGroups uitgevouwen6" = Table.ExpandTableColumn(#"Query's samengevoegd6", "ItemGroups", {"Code", "Description"}, {"ItemGroups.Code", "ItemGroups.Description"}),
    #"Kolommen verwijderd" = Table.RemoveColumns(#"ItemGroups uitgevouwen6",{"AssimilatedVATBox", "BelcotaxType", "Compress", "Costcenter", "CostcenterDescription", "Costunit", "CostunitDescription", "Created", "Creator", "CreatorFullName", "DescriptionTermID", "ExcludeVATListing", "ExpenseNonDeductiblePercentage", "IsBlocked", "Matching", "Modified", "Modifier", "ModifierFullName", "PrivateGLAccount", "PrivatePercentage", "ReportingCode", "RevalueCurrency", "SearchCode", "UseCostcenter", "UseCostunit", "VATCode", "VATDescription", "VATGLAccountType", "VATNonDeductibleGLAccount", "VATNonDeductiblePercentage", "VATSystem", "YearEndCostGLAccount", "YearEndReflectionGLAccount", "CreatedUtc", "ModifiedUtc", "Division", "DivisionShortName", "DivisionCompanyCoCNumber", "DivisionCompanyIBANNumber", "DivisionCompanyRSINNumber", "DivisionCompanyVATNumber", "DivisionCompanyWageTaxNumber", "DivisionName", "DivisionLabel", "DivisionCompanyName", "DivisionOwnerCompanyName", "DivisionOwnerCompanyNumber"})
in
    #"Kolommen verwijderd"

De volgende stap in Power BI:

#"ItemGroups uitgevouwen3" = Table.ExpandTableColumn(#"Query's samengevoegd3", "ItemGroups", {"ID", "GLRevenue"}, {"ItemGroups.ID.3", "ItemGroups.GLRevenue"}),

voegt de voorgaande resultaten samen met de ItemGroups. Dit zijn de artikelgroepen uit Exact Online. Echter, er kunnen meerdere artikelgroepen zijn met deze grootboekrekening. Mogelijk is het verstandig om deze stap te corrigeren om dubbele rijen te voorkomen, nu of in de toekomst wijzigingen in de administratie, zodat Power BI en Exact Online goed op elkaar afgestemd zijn.

Verkeerde Cardinaliteit GLAccountClassificationMappings

De Exact tabel GLAccountClassificationMappings bevat een afbeelding van grootboekrekeningen naar de verdichtingen. Echter, er kunnen meerdere rapportagestructuren zijn met meerdere verdichtingen. Hierdoor kan een rij meerdere keren terugkomen afhankelijk van de configuratie, 1 keer voor elke rapportagestructuur gedefinieerd in Exact Online. Een voorbeeld:

Dit kan afhankelijk van de administratieve inrichting in Exact bij het importeren uit Exact Online in Power BI leiden tot een fout in rapportages zoals:

Exact Online GLAccountClassificationMappings Power BI error

Column ‘GLAccount’ in Table ‘GLAccountClassificationMappings’ contains a duplicate value ‘…’ and this is not allowed for columns on the one side of a many-to-one relationship or for columns that are used as the primary key of a table.

Advies is om zoals in het Exact Online datamodel zichtbaar te filteren op de rapportagestructuur. Dat kan door te zoeken op de waarde voor GLSchemeCode; meestal is de waarde ‘1’ gewenst, maar de administrateur of accountant kan eigen waardes toevoegen in Exact. Ook kan RGS geactiveerd worden.