Search code examples
delphifastreport

Distinct Count in fastreport


Does anyone know how to make a distinct count in fastreport? Example I have the report:

 Name   sex
 João    m
 João    m
 Maria   f

In the normal count, the result would be 3, but I want one that takes only the number of rows that do not repeat the field name . In this case, the result would be 2. Can anyone help me? That's just an example. I can not do a group by in SQL because I have several fields.


Solution

  • I'm not skilled in using FastReport but I've found this page on the FastReport's official forum.

    I think you can change the example by adapting it to your scenario (Note that the syntax could require some adjustments).

    Bands:

    GroupHeader1 <Sex> 
    MasterData1 [Name, Sex, ...] 
    GroupFooter1 [GetDistinctCount]
    

    Script (Only working with dataset sorted by the field to count):

    var 
      LastValue : string;
      DistinctCount : integer;
    
    //create this event by double-clicking the event from the Object Inspector
    procedure OnGroupHeader1.OnBeforePrint;
    begin
      if LastValue <> (<Datasetname."Sex">) then
        Inc(DinstinctCount);
    
      LastValue := <Datasetname."Sex">
    end;
    
    function GetDistinctCount: string;
    begin
      Result := IntToStr(DistinctCount);
    end;
    

    The base idea is that the DistinctCount variable is incremented each time the field value changes.

    Script (Should works also with unsorted dataset):

    var 
      FoundValues : array of string;
    
    
    (* !!IMPORTANT!!
    You need to initialize FoundValues array before to start counting: *)
    SetLength(FoundValues, 0);
    
    
    function IndexOf(AArray : array of string; const AValue : string) : integer;
    begin
      Result := 0;
      while(Result < Length(AArray)) do
      begin
        if(AArray[Result] = AValue) then
          Exit;
        Inc(Result);
      end;
      Result := -1;
    end;
    
    //create this event by double-clicking the event from the Object Inspector
    procedure OnGroupHeader1.OnBeforePrint;
    begin
      if(IndexOf(FoundValues, <Datasetname."Sex">) = -1) then
      begin
        SetLength(FoundValues, Length(FoundValues) + 1);
        FoundValues[Length(FoundValues) - 1] := <Datasetname."Sex">;
      end;
    end;
    
    function GetDistinctCount: string;
    begin
      Result := IntToStr(Length(FoundValues));
    end;
    

    The base idea is that each different value found is added to the FoundValues array.