Kennisbank

Firedac dataset aggregaties

Wist je dat je in een Firedac query of table kunt werken met runtime aggregraties op dataset niveau? Een totaal bedrag van alle geladen orders weergeven, of een totaal van alle orders die nog verzonden moeten worden kan heel eenvoudig zonder dat je een losse query nodig hebt.

Misschien was je al bekend met een aggregrated field, maar dat beperkt zich tot rijniveau. Met de property Aggregrates van een TFDDataSet kun je echter ook totaliseren op dataset niveau.

Als voorbeeld heb ik een demo programma waarin ik alle orders uit een database ophaal in een tabel. Die kan ik filteren op store id. Rechtsboven in beeld zie je het aantal nog te verzenden orders. Dit getal wordt berekend door een aggregrated field van de query.

Om te beginnen definieer ik een aggregratie field in de aggregrations property van de query. Het belangrijkste veld hier is Expression. Hier wordt de aggregratie gedefinieerd die we willen uitvoeren. Eventueel met een voorwaarde er in. Hier wordt de standaard Firedac expression syntax voor gebruikt.

In bovenstaand voorbeeld tel ik het aantal records (COUNT) van het veld Shipped_Date met als voorwaarde dat dit veld alleen geteld wordt als de waarde leeg is. Daarvoor kan de functie IIF gebruikt worden. Andere eenvoudige voorbeelden die je hier kunt gebruiken zijn:

SUM(order_amount)

MIN(order_date)

Zoals je kunt zien in de properties kun je een field op active zetten. Doe je dat niet, dan wordt het uiteraard niet berekend. Een naam kan ook handig zijn, om in de code de aggegratie terug te kunnen vinden.

Helaas kun je een aggegratie niet als een database veld linken aan een data-aware control. Het weergeven moet dus in code geregeld worden. Hiervoor heb ik een aparte procedure gemaakt, zodat ik die eenvoudig kan aanroepen als een refresh nodig is. Deze procedure roep ik aan in het AfterOpen event van de query en als er gefilterd wordt op een store.

procedure TfrmDemoApp.qryOrdersAfterOpen(DataSet: TDataSet);
begin
  ShowNotShippedAggregation;
end;

procedure TfrmDemoApp.ShowNotShippedAggregation;
begin
  var NotShipped := qryOrders.Aggregates.Items[0].Value;

  if NotShipped = Null then
     lblNotShipped.Caption := '0'
  else
    lblNotShipped.Caption := NotShipped;
end;

Vergeet niet op de query de property AggegratesActive op True te zetten, anders worden de aggegraties niet uitgerekend. Een ander punt om rekening mee te houden: de aggegraties werken op de data die opgehaald is in de dataset. Standaard haalt Firedac 50 records op. Wil je een totaal wat gebaseerd is op alle records ga dan naar de FetchOptions in de query properties en zet de Mode op fmAll.

Zie hieronder het resultaat in de demo applicatie.

Geschreven door Kees de Kraker
Directeur

Contact

Laat ons helpen jouw ambities concreet te maken.