Filtering OData Feeds

Last time we talked about getting OData Feeds into Excel, this time let’s talk about how to filter that OData Feeds.

When you connect and pull data using OData, it pulls ALL the records from the feed that you have selected. If you are dealing with large data, it is expensive to pull large data every single time you do the pull. Historical data such as ledgers can take from minutes to hours to pull it. It can be frustrating when you need to wait for a very long time, especially when you are planning to use only a small subset of the data.

There is also another case where you need to limit the data for security reason.

Regardless of the reasons, there is an advantage to be able to pull only the data you need. This can be achieved by using Filter Expression on the OData Feed.

To add a filter to OData, add $filter= at the end of the URL.

Let’s take an example of Vendor Ledger Entries OData. Below is the result if you pull the data as it is.

Let’s try pull only data for Vendor No. = 20000.

Original:
https://api.businesscentral.dynamics.com/v2.0/e6x7218c-xxxx-xxxx-xxxx-c9a01375b7f6/Sandbox/ODataV4/Company('CRONUS%20NZ')/VendorLedgerEntries

With Filter:
https://api.businesscentral.dynamics.com/v2.0/e6x7218c-xxxx-xxxx-xxxx-c9a01375b7f6/Sandbox/ODataV4/Company('CRONUS%20NZ')/VendorLedgerEntries?$filter=Vendor_No eq '20000'

We can see that it only pulls records with Vendor No. 20000.

Only Vendor 20000

Let’s try putting more filter, such as any records with due date up to 31 January 2019.

Original:
https://api.businesscentral.dynamics.com/v2.0/e6x7218c-xxxx-xxxx-xxxx-c9a01375b7f6/Sandbox/ODataV4/Company('CRONUS%20NZ')/VendorLedgerEntries

With Filter:
https://api.businesscentral.dynamics.com/v2.0/e6x7218c-xxxx-xxxx-xxxx-c9a01375b7f6/Sandbox/ODataV4/Company('CRONUS%20NZ')/VendorLedgerEntries?$filter=Vendor_No eq '20000' and Posting_Date le 2019-01-31

Filtered by Vendor No and Posting Date

If you want to limit the fields that you pull, you can use $select. Use & to combine $select and $filter.

Let’s try getting only Vendor No, Document No, and Posting Date fields. Less data is always good.

Original:
https://api.businesscentral.dynamics.com/v2.0/e6x7218c-xxxx-xxxx-xxxx-c9a01375b7f6/Sandbox/ODataV4/Company('CRONUS%20NZ')/VendorLedgerEntries

With Filter and Select:
https://api.businesscentral.dynamics.com/v2.0/e6x7218c-xxxx-xxxx-xxxx-c9a01375b7f6/Sandbox/ODataV4/Company('CRONUS%20NZ')/VendorLedgerEntries?$select=Vendor_No,Document_No,Posting_Date&$filter=Vendor_No eq '20000' and Posting_Date le 2019-01-31

If we try to do $select in Excel, it will return errors for each of the fields that you do not specify in the $select statement. You need to make sure to remove the Columns using Power Query Editor.

Excel Error
Remove Columns

However, if you try to use the normal web services, you can see that it only pulls the specified fields.

Access via browser

Below are some of the list of filtering expressions that you can use.

DefinitionExample and explanationEquivalent C/AL expression
Select a range of valuesfilter=Entry_No gt 610 and Entry_No lt 615

Query on GLEntry service. Returns entry numbers 611 through 614.
..
Andfilter=Country_Region_Code eq 'ES' and Payment_Terms_Code eq '14 DAYS'

Query on Customer service. Returns customers in Spain where Payment_Terms_Code=14 DAYS.
&
Orfilter= Country_Region_Code eq 'ES' or Country_Region_Code eq 'US'

Query on Customer service. Returns customers in Spain and the United States.

Alert: You can use OR operators to apply different filters on the same field. However, you cannot use OR operators to apply filters on two different fields.
|
Less thanfilter=Entry_No lt 610

Query on GLEntry service. Returns entry numbers that are less than 610.
<
Greater thanfilter= Entry_No gt 610

Query on GLEntry service. Returns entry numbers 611 and higher.
>
Greater than or equal tofilter=Entry_No ge 610

Query on GLEntry service. Returns entry numbers 610 and higher.
>=
Less than or equal tofilter=Entry_No le 610

Query on GLEntry service. Returns entry numbers up to and including 610.
<=
Different from (not equal)filter=VAT_Bus_Posting_Group ne 'EXPORT'

Query on Customer service. Returns all customers with VAT_Bus_Posting_Group not equal to EXPORT.
<>
endswithfilter=endswith(VAT_Bus_Posting_Group,'RT')

Query on Customer service. Returns all customers with VAT_Bus_Posting_Group values that end in RT.
*
startswithfilter=startswith(Name, 'S')

Query on Customer service. Returns all customers names beginning with “S”.
substringoffilter=substringof(Name, ‘urn’)

Query on Customer service. Returns customer records for customers with names containing the string “urn”.
indexoffilter=indexof(Location_Code, ‘BLUE’) eq 0

Query on Customer service. Returns customer records for customers having a location code beginning with the string BLUE.
replacefilter=replace(City, 'Miami', 'Tampa') eq 'CODERED'
substringfilter=substring(Location_Code, 5) eq 'RED'

Query on Customer service. Returns true for customers with the string RED in their location code starting as position 5.
tolowerfilter=tolower(Location_Code) eq 'code red'
toupperfilter=toupper(FText) eq '2ND ROW'
trimfilter=trim(FCode) eq 'CODE RED'
concatfilter=concat(concat(FText, ', '), FCode) eq '2nd row, CODE RED'
roundfilter=round(FDecimal) eq 1
floorfilter=floor(FDecimal) eq 0
ceilingfilter=ceiling(FDecimal) eq 1
Filter Expression

You can refer Microsoft Docs to learn more about filtering.

thatnavguy

Experienced NZ-based NAV Developer and Consultant with 15+ years of experience leading multiple IT projects, performing business analyst, developing, implementing, and upgrading Dynamics NAV and Business Central. Passionate to deliver solution that focuses on user-friendly interface while keeping high standard of compliance with the needs.

You may also like...

4 Responses

  1. Carolee says:

    Hi,

    Now that we know how to use query expressions in an Odata request, I’d like to examine the expression from within the Odata API page so I can do some other work with it. Is that possible?

    • thatnavguy says:

      If I understand your question correctly, there is currently no way to check the expression from the page.

      • Carolee says:

        Thanks for the response.

        I discovered that I can send a $filter for a flowfilter field and it calculates automatically. That eliminates my need to examine the Odata request to get a parameter value from it for this problem, but it’s too bad that’s not an option.

  2. Amabelle says:

    Hi, what if if, instead of a general ledger, we connect a trial balance, is there still the ability to filter as to balance per date?

Leave a Reply

Your email address will not be published. Required fields are marked *