Learn how to query data (more than 5000 items) faster from a SharePoint list in Power BI
The challenge
When refreshing data in Power BI from SharePoint, and using the standard SharePoint connecter, the refresh can be painfully slow.
Also, when getting more than 5000 items, and trying to do an incremental refresh, you might also have encountered this error
This dataset includes a dynamic data source. Since dynamic data sources aren’t refreshed in the Power BI service, this dataset won’t be refreshed.
Let’s query data in a faster way that also works with scheduled refresh
The solution
A few things we need to consider
- We need to be able to get more than 5000 elements
- We need to avoid using dynamic data
- We might need to expand column types like people or lookup fields
Step 1
In Power Query create a new blank query and click advanced editor
Insert the following code (with needed adjustments, explained below the code snippet)
let
BaseURL = "https://yourtenant.sharepoint.com/sites/yoursitename/",
ListName = "yourListName",
ExpandColumns = "Author/Title,Editor/Title",
Expand = "Author,Editor",
CountItems = Json.Document(Web.Contents(BaseURL, [RelativePath = "_api/web/lists/GetByTitle('" & ListName & "')/items?$select=ID&$orderby=ID%20desc&$top=1", Headers = [Accept = "application/json"]]))[value]{0}[ID],
StartID = List.Numbers(0, Number.RoundUp(CountItems / 5000), 5000),
#"Converted to Table" = Table.FromList(StartID, Splitter.SplitByNothing(), null, null, ExtraValues.Error),
EndID = Table.AddColumn(#"Converted to Table", "Custom", each [Column1] + 4999, type number),
#"Renamed Columns" = Table.RenameColumns(EndID,{{"Column1", "StartID"}, {"Custom", "EndID"}}),
#"Changed Type" = Table.TransformColumnTypes(#"Renamed Columns",{{"StartID", type text}, {"EndID", type text}}),
selectedfields = "&$top=5000&$select=*," & ExpandColumns & "&$expand=" & Expand,
ListItems = Table.AddColumn(#"Changed Type", "ListItems", each Json.Document(Web.Contents(BaseURL, [RelativePath = "_api/web/lists/GetByTitle('" & ListName & "')/items?$filter=(ID ge " & [StartID] & ") and (ID le " & [EndID] & ")&$top=5000&$select=*," & ExpandColumns & "&$expand=" & Expand, Headers = [Accept = "application/json"]]))[value]),
#"Removed Other Columns" = Table.SelectColumns(ListItems,{"ListItems"}),
#"Expanded ListItems" = Table.ExpandListColumn(#"Removed Other Columns", "ListItems")
in
#"Expanded ListItems"
Change the following variables
-
BaseUrl
Change to your own site (don’t forget the last /) -
ListName:
Change to your list name (the actual name, the one you see on your site) -
ExpandColumns:
If you want to expand any columns like a people field, and get the title (name) or the EMail, you insert the expand columns here, like below:
ExpandColumns = "Author/Title,Editor/Title,PersonColumn/EMail,PersonColumn/Title,LookupColumn/Title",
-
Expand:
Everytime you introduce a new column to expand, it is important you write the name here, like this:
Expand = "Author,Editor,PersonColumn,LookupColumn",
Step 2
You can now select the arrow icon and click expand
Unclick use original column name as prefix and click OK
Your list is now ready, and you can begin to expand your columns.
Notice that everytime you introduce a new column, you need to go back to this step, and select the new column
Note the that code above will only work if you have at least 1 expand column introduced.
Further refinement
The code above is currently selecting all the non-expandable columns in your list, so you can improve the code even further, by selecting ONLY the columns that you need
In this part of the code, replace the asterix * in the code below, with the columns that you need
selectedfields = "&$top=5000&$select=*," & ExpandColumns & "&$expand=" & Expand,
Here is an example
selectedfields = "&$top=5000&$select=ID,ProjectName,Title,Street," & ExpandColumns & "&$expand=" & Expand,
And also here
[EndID] & ")&$top=5000&$select=*," & ExpandColumns & "&$expand=" & Expand, Headers = [Accept = "application/json"]]))[value]),
Like
[EndID] & ")&$top=5000&$select=ID,ProjectName,Title,Street," & ExpandColumns & "&$expand=" & Expand, Headers = [Accept = "application/json"]]))[value]),
Another thing to consider is if you really need to expand the people columns.
Instead you could get the UserInformationList from SharePoint, and combine that table with the peopleId
I got the inspiration to this solution from Peter Tadrous
See also
- Create dynamic dates in Power BI with OData
- Update metadata for locked/checked out/need approval files
- Calculate age, anniversary and milestone birthday in Power BI
- Trigger a Power Automate Flow with modern ribbon, with a custom button in Dynamics 365 (not Ribbon Workbench)
- Make an API request with a custom button (Modern Ribbon)