Răsfoiți Sursa

* Modified Patch from Pascal Riekenberg to implement VisibleExpr, plus some refactoring

git-svn-id: trunk@37045 -
michael 8 ani în urmă
părinte
comite
a8aab3ea97
2 a modificat fișierele cu 255 adăugiri și 132 ștergeri
  1. 25 3
      packages/fcl-report/demos/rptgrouping.pp
  2. 230 129
      packages/fcl-report/src/fpreport.pp

+ 25 - 3
packages/fcl-report/demos/rptgrouping.pp

@@ -131,7 +131,7 @@ begin
 
   GroupHeader := TFPReportGroupHeaderBand.Create(p);
   GroupHeader.Layout.Height := 15;
-  GroupHeader.GroupCondition := 'copy(''[country]'',1,1)';
+  GroupHeader.GroupCondition := 'copy(country,1,1)';
   {$ifdef ColorBands}
   GroupHeader.Frame.Shape := fsRectangle;
   GroupHeader.Frame.BackgroundColor := clGroupHeaderFooter;
@@ -152,20 +152,42 @@ begin
   DataBand.Frame.Shape := fsRectangle;
   DataBand.Frame.BackgroundColor := clDataBand;
   {$endif}
+  //DataBand.VisibleExpr := 'StrToFloat(''[population]'') > 50000000';
 
   Memo := TFPReportMemo.Create(DataBand);
   Memo.Layout.Left := 15;
-  Memo.Layout.Top := 0;
+  Memo.Layout.Top := 2;
   Memo.Layout.Width := 50;
   Memo.Layout.Height := 5;
   Memo.Text := '[country]';
 
   Memo := TFPReportMemo.Create(DataBand);
   Memo.Layout.Left := 70;
-  Memo.Layout.Top := 0;
+  Memo.Layout.Top := 2;
   Memo.Layout.Width := 30;
   Memo.Layout.Height := 5;
   Memo.Text := '[formatfloat(''#,##0'', StrToFloat(population))]';
+  //Memo.VisibleExpr := 'StrToFloat(''[population]'') > 50000000';
+
+  Memo := TFPReportMemo.Create(DataBand);
+  Memo.Layout.Left := 105;
+  Memo.Layout.Top := 2;
+  Memo.Layout.Width := 50;
+  Memo.Layout.Height := 5;
+  Memo.Text := '> Germany';
+  Memo.UseParentFont := false;
+  Memo.Font.Color := clGreen;
+  Memo.VisibleExpr := 'StrToFloat(population) > 80890000';
+
+  Memo := TFPReportMemo.Create(DataBand);
+  Memo.Layout.Left := 105;
+  Memo.Layout.Top := 2;
+  Memo.Layout.Width := 50;
+  Memo.Layout.Height := 5;
+  Memo.Text := '< Germany';
+  Memo.UseParentFont := false;
+  Memo.Font.Color := clRed;
+  Memo.VisibleExpr := 'StrToFloat(population) < 80890000';
 
 
   PageFooter := TFPReportPageFooterBand.Create(p);

+ 230 - 129
packages/fcl-report/src/fpreport.pp

@@ -608,11 +608,17 @@ type
     FRTLayout: TFPReportLayout;
     FOnBeforePrint: TFPReportBeforePrintEvent;
     FStretchMode: TFPReportStretchMode;
+    FVisibleExpr: String;
     function GetReport: TFPCustomReport;
     procedure SetFrame(const AValue: TFPReportFrame);
     procedure SetLayout(const AValue: TFPReportLayout);
     procedure SetVisible(const AValue: boolean);
+    procedure SetVisibleExpr(AValue: String);
   protected
+    function GetDateTimeFormat: String; virtual;
+    function ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString; virtual;
+    function GetReportBand: TFPReportCustomBand; virtual;
+    function GetReportPage: TFPReportCustomPage; virtual;
     Procedure SaveDataToNames; virtual;
     Procedure RestoreDataFromNames; virtual;
     function CreateFrame: TFPReportFrame; virtual;
@@ -627,6 +633,8 @@ type
     procedure Notification(AComponent: TComponent; Operation: TOperation); override;
     { triggers OnBeforePrint event }
     procedure BeforePrint; virtual;
+    function EvaluateExpression(const AExpr: String; out Res: TFPExpressionResult): Boolean;
+    function EvaluateExpressionAsText(const AExpr: String): String;
     { this is run against the runtime (RT) version of this element, and before BeforePrint is called. }
     procedure RecalcLayout; virtual; abstract;
     property  StretchMode: TFPReportStretchMode read FStretchMode write FStretchMode default smDontStretch;
@@ -641,6 +649,7 @@ type
     procedure Assign(Source: TPersistent); override;
     procedure BeginUpdate;
     procedure EndUpdate;
+    function EvaluateVisibility : boolean;
     property Parent: TFPReportElement read FParent write SetParent;
     Property Report : TFPCustomReport read GetReport;
     { Runtime Layout - populated when layouting of report is calculated. }
@@ -649,6 +658,9 @@ type
     property Layout: TFPReportLayout read FLayout write SetLayout;
     property Frame: TFPReportFrame read FFrame write SetFrame;
     property Visible: boolean read FVisible write SetVisible;
+    property VisibleExpr: String read FVisibleExpr write SetVisibleExpr;
+    property Page: TFPReportCustomPage read GetReportPage;
+    property Band: TFPReportCustomBand read GetReportBand;
   end;
 
 
@@ -761,6 +773,10 @@ type
     procedure SetColumnLayout(AValue: TFPReportColumnLayout);
     procedure SetColumnCount(AValue: Byte);
     procedure SetColumnGap(AValue: TFPReportUnits);
+    function GetReportPage: TFPReportCustomPage; override;
+    function GetReportBand: TFPReportCustomBand; override;
+    property Band;
+    property Page;
   protected
     Procedure SaveDataToNames; override;
     Procedure RestoreDataFromNames; override;
@@ -817,7 +833,7 @@ type
     FVisibleOnPage: TFPReportVisibleOnPage;
     FFont: TFPReportFont;
     function    GetFont: TFPReportFont;
-    function    GetReportPage: TFPReportCustomPage;
+    function    GetReportPage: TFPReportCustomPage; override;
     function    IsStringValueZero(const AValue: string): boolean;
     procedure   SetChildBand(AValue: TFPReportChildBand);
     procedure   ApplyStretchMode;
@@ -828,7 +844,6 @@ type
     function    GetReportBandName: string; virtual;
     function    GetData: TFPReportData; virtual;
     procedure   SetDataFromName(AName : String); virtual;
-    function    ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString; virtual;
     procedure   SetParent(const AValue: TFPReportElement); override;
     procedure   CreateRTLayout; override;
     procedure   PrepareObjects; override;
@@ -847,7 +862,6 @@ type
     Class Function ReportBandType : TFPReportBandType; virtual;
     procedure   WriteElement(AWriter: TFPReportStreamer; AOriginal: TFPReportElement = nil); override;
     procedure   ReadElement(AReader: TFPReportStreamer); override;
-    property    Page: TFPReportCustomPage read GetReportPage;
   end;
   TFPReportCustomBandClass = Class of TFPReportCustomBand;
 
@@ -1006,8 +1020,11 @@ type
   end;
 
 
+  { TFPReportCustomGroupHeaderBand }
+
   TFPReportCustomGroupHeaderBand = class(TFPReportCustomBandWithData)
   private
+    FConditionValue: string;
     FGroupHeader: TFPReportCustomGroupHeaderBand;
     FChildGroupHeader: TFPReportCustomGroupHeaderBand;
     FGroupFooter: TFPReportCustomGroupFooterBand;
@@ -1015,6 +1032,7 @@ type
     procedure   SetGroupHeader(AValue: TFPReportCustomGroupHeaderBand);
   protected
     function    GetReportBandName: string; override;
+    Procedure   CalcGroupConditionValue;
     procedure   DoWriteLocalProperties(AWriter: TFPReportStreamer; AOriginal: TFPReportElement = nil); override;
     procedure   Notification(AComponent: TComponent; Operation: TOperation); override;
     { This property defines the hierarchy of nested groups. For the top most group, this property will be nil. }
@@ -1023,6 +1041,8 @@ type
     property    GroupFooter: TFPReportCustomGroupFooterBand read FGroupFooter;
     { can be a field name or an expression }
     property    GroupCondition: string read FCondition write FCondition;
+    { Run-time calculated value }
+    property    GroupConditionValue : string read FConditionValue write FConditionValue;
   public
     constructor Create(AOwner: TComponent); override;
     procedure   Assign(Source: TPersistent); override;
@@ -3782,7 +3802,7 @@ var
   lBand: TFPReportCustomBand;
   lMemo: TFPReportCustomMemo;
 begin
-  if not self.Visible then
+  if not self.EvaluateVisibility then
     Exit;
   if Parent is TFPReportCustomBand then
   begin
@@ -4002,7 +4022,7 @@ var
   lBand: TFPReportCustomBand;
   lShape: TFPReportCustomShape;
 begin
-  if not self.Visible then
+  if not self.EvaluateVisibility then
     Exit;
   if Parent is TFPReportCustomBand then
     begin
@@ -4171,7 +4191,7 @@ var
   lBand: TFPReportCustomBand;
   lImage: TFPReportCustomImage;
 begin
-  if not self.Visible then
+  if not self.EvaluateVisibility then
     Exit;
   if Parent is TFPReportCustomBand then
   begin
@@ -4351,7 +4371,7 @@ var
   lBand: TFPReportCustomBand;
   lCB: TFPReportCustomCheckbox;
 begin
-  if not self.Visible then
+  if not self.EvaluateVisibility then
     Exit;
   if Parent is TFPReportCustomBand then
   begin
@@ -4613,6 +4633,11 @@ begin
   Result := 'GroupHeaderBand';
 end;
 
+procedure TFPReportCustomGroupHeaderBand.CalcGroupConditionValue;
+begin
+  GroupConditionValue:=Evaluate;
+end;
+
 procedure TFPReportCustomGroupHeaderBand.DoWriteLocalProperties(AWriter: TFPReportStreamer; AOriginal: TFPReportElement);
 begin
   inherited DoWriteLocalProperties(AWriter, AOriginal);
@@ -4648,7 +4673,7 @@ end;
 
 function TFPReportCustomGroupHeaderBand.Evaluate: string;
 begin
-  Result := ExpandMacro(GroupCondition, True);
+  Result := EvaluateExpressionAsText(GroupCondition);
 end;
 
 class function TFPReportCustomGroupHeaderBand.ReportBandType: TFPReportBandType;
@@ -5190,6 +5215,34 @@ begin
     Result:=TFPReportCustomPage(el).Report;
 end;
 
+function TFPReportElement.GetReportBand: TFPReportCustomBand;
+begin
+  if (Self is TFPReportCustomBand) then
+    Result := Self as TFPReportCustomBand
+  else if (Parent is TFPReportCustomBand) then
+    Result := Parent as TFPReportCustomBand
+  else
+    Result := nil;
+end;
+
+function TFPReportElement.EvaluateVisibility: boolean;
+
+var
+  Res : TFPExpressionResult;
+
+begin
+  Result := Visible;
+  if Result and (FVisibleExpr <> '') then 
+    begin
+    if EvaluateExpression(FVisibleExpr,res) then
+      if (res.ResultType=rtBoolean) then // We may need to change this.
+        Result:= Res.ResBoolean;
+    {$ifdef gdebug}
+    writeln('TFPReportElement.EvaluateVisibility: VisibleExpr=' , FVisibleExpr , '=' , Res.ResultType,' : ',Res.ResBoolean);
+    {$endif}
+    end;
+end;
+
 procedure TFPReportElement.SetLayout(const AValue: TFPReportLayout);
 begin
   if FLayout = AValue then
@@ -5227,6 +5280,110 @@ begin
   Changed;
 end;
 
+procedure TFPReportElement.SetVisibleExpr(AValue: String);
+begin
+  if FVisibleExpr=AValue then Exit;
+  FVisibleExpr:=AValue;
+  Changed;
+end;
+
+function TFPReportElement.ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString;
+
+var
+  pstart: integer;
+  pend: integer;
+  len: integer;
+  m: string;  // macro
+  mv: string; // macro value
+  r: string;
+  lFoundMacroInMacro: boolean;
+
+begin
+  r := s;
+  lFoundMacroInMacro := False;
+  pstart := Pos('[', r);
+  while (pstart > 0) or lFoundMacroInMacro do
+  begin
+    if lFoundMacroInMacro then
+    begin
+      pstart := Pos('[', r);
+      lFoundMacroInMacro := False;
+    end;
+    len := Length(r);
+    pend := pstart + 2;
+    while pend < len do
+    begin
+      if r[pend] = '[' then  // a macro inside a macro
+      begin
+        lFoundMacroInMacro := True;
+        pstart := pend;
+      end;
+      if r[pend] = ']' then
+        break
+      else
+        inc(pend);
+    end;
+
+    m := Copy(r, pstart, (pend-pstart)+1);
+    if (m = '[PAGECOUNT]') and Page.Report.TwoPass and Page.Report.IsFirstPass then
+    begin
+      // replace macro with a non-marco marker. We'll replace the marker in the second pass of the report.
+      r := StringReplace(r, m, cPageCountMarker, [rfReplaceAll, rfIgnoreCase]);
+      // look for more macros
+      pstart := Pos('[', r);
+      Continue;
+    end;
+
+    len := Length(m);
+    try
+      if Assigned(Band.GetData) then
+      begin
+        try
+          mv := Band.GetData.FieldValues[Copy(m, 2, len-2)];
+        except
+          on e: EVariantTypeCastError do  // maybe we have an expression not data field
+          begin
+            mv := EvaluateExpressionAsText(Copy(m, 2, len-2));
+          end;
+        end;
+      end
+      else
+      begin // No Data assigned, but maybe we have an expression
+        mv := EvaluateExpressionAsText(Copy(m, 2, len-2));
+      end;
+    except
+      on e: EVariantTypeCastError do    // ReportData.OnGetValue did not handle all macros, so handle this gracefully
+        mv := SErrUnknownMacro+': '+copy(m,2,len-2);
+      on e: EExprParser do
+        mv := SErrUnknownMacro+': '+copy(m,2,len-2);
+    end;
+    r := StringReplace(r, m, mv, [rfReplaceAll, rfIgnoreCase]);
+    // look for more macros
+    pstart := PosEx('[', r,PStart+Length(mv));
+  end;
+  { This extra check is mostly for ReportGroupHeader expression processing }
+  if (pstart = 0) and Assigned(Band.GetData) and AIsExpr then
+  begin
+    try
+      r := EvaluateExpressionAsText(r);
+    except
+      on E: Exception do
+      begin
+        { $ifdef gdebug}
+        writeln('ERROR in expression: ', E.Message);
+        { $endif}
+        // do nothing - move on as we probably handled the expression a bit earlier in this code
+      end;
+    end;
+  end;
+  Result := r;
+end;
+
+function TFPReportElement.GetReportPage: TFPReportCustomPage;
+begin
+  Result := Band.Page;
+end;
+
 procedure TFPReportElement.SaveDataToNames;
 begin
   // Do nothing
@@ -5270,7 +5427,7 @@ var
   EL : TFPReportElement;
 
 begin
-  if not self.Visible then
+  if not self.EvaluateVisibility then
     Exit;
   if Parent is TFPReportCustomBand then
     begin
@@ -5338,11 +5495,49 @@ begin
     FOnBeforePrint(self);
 end;
 
+function TFPReportElement.EvaluateExpression(const AExpr: String; Out Res: TFPExpressionResult) : Boolean;
+
+var
+  lExpr: TFPExpressionParser;
+
+begin
+  Result:=Assigned(Report);
+  if not Result then
+    exit;
+  lExpr := Report.FExpr;
+  lExpr.Expression := AExpr;
+  Res:=lExpr.Evaluate;
+end;
+
+Function TFPReportElement.GetDateTimeFormat : String;
+
+begin
+  Result:='yyyy-mm-dd';
+end;
+
+function TFPReportElement.EvaluateExpressionAsText(const AExpr: String): String;
+
+Var
+  Res : TFPExpressionResult;
+
+begin
+  Result:='';
+  if EvaluateExpression(AExpr,Res) then
+    case Res.ResultType of
+      rtString  : Result := Res.ResString;
+      rtInteger : Result := IntToStr(Res.ResInteger);
+      rtFloat   : Result := FloatToStr(Res.ResFloat);
+      rtBoolean : Result := BoolToStr(Res.resBoolean, True);
+      rtDateTime : Result := FormatDateTime(GetDateTimeFormat, Res.resDateTime);
+    end;
+end;
+
+
 function TFPReportElement.Equals(AElement: TFPReportElement): boolean;
 begin
   Result := (AElement = Self) or ((AElement.ClassType = AElement.ClassType) and
     (AElement.Frame.Equals(Self.Frame)) and (AElement.Layout.Equals(Self.Layout))
-    and (AElement.Visible = Self.Visible));
+    and (AElement.Visible = Self.Visible) and (AElement.VisibleExpr = Self.VisibleExpr));
 end;
 
 procedure TFPReportElement.WriteElement(AWriter: TFPReportStreamer; AOriginal: TFPReportElement);
@@ -5379,6 +5574,7 @@ begin
     end;
   end;
   AWriter.WriteBoolean('Visible', FVisible);
+  AWriter.WriteString('VisibleExpr', FVisibleExpr);
   AWriter.WriteString('StretchMode', StretchModeToString(StretchMode));
   DoWriteLocalProperties(AWriter, AOriginal);
 end;
@@ -5409,6 +5605,7 @@ begin
     end;
   end;
   FVisible := AReader.ReadBoolean('Visible', Visible);
+  FVisibleExpr := AReader.ReadString('VisibleExpr', FVisibleExpr);
   FStretchMode := StringToStretchMode(AReader.ReadString('StretchMode', 'smDontStretch'));
   // TODO: implement reading OnBeforePrint information
 end;
@@ -5426,6 +5623,7 @@ begin
     Layout.Assign(E.Layout);
     FParent := E.Parent;
     Visible := E.Visible;
+    VisibleExpr := VisibleExpr;
     StretchMode := E.StretchMode;
     OnBeforePrint := E.OnBeforePrint;
   end;
@@ -5674,6 +5872,16 @@ begin
   RecalcLayout;
 end;
 
+function TFPReportCustomPage.GetReportPage: TFPReportCustomPage;
+begin
+  Result := nil;
+end;
+
+function TFPReportCustomPage.GetReportBand: TFPReportCustomBand;
+begin
+  Result := nil;
+end;
+
 procedure TFPReportCustomPage.SaveDataToNames;
 begin
   inherited ;
@@ -6035,7 +6243,7 @@ begin
   for i := ABand.ChildCount-1 downto 0 do
   begin
     e := ABand.Child[i];
-    if not e.Visible then
+    if not e.EvaluateVisibility then
     begin
       ABand.RemoveChild(e);
       FreeAndNil(e);
@@ -6607,7 +6815,7 @@ var
   begin
     lLastDsgnDataBand := ADsgnBand;
     CommonRuntimeBandProcessing(ADsgnBand);
-    if lRTBand.Visible then
+    if lRTBand.EvaluateVisibility then
     begin
       lLastDataBand := lRTBand;
       RecalcBandLayout(lRTBand);
@@ -6637,7 +6845,7 @@ var
       while lDsgnChildBand <> nil do
       begin
         CommonRuntimeBandProcessing(lDsgnChildBand);
-        if lRTBand.Visible then
+        if lRTBand.EvaluateVisibility then
         begin
           RecalcBandLayout(lRTBand);
           UpdateSpaceRemaining(lRTBand);
@@ -6685,7 +6893,7 @@ var
       Exit; // nothing further to do
 
     CommonRuntimeBandProcessing(ADsgnBand);
-    if lRTBand.Visible then
+    if lRTBand.EvaluateVisibility then
     begin
       lDataHeaderPrinted := True;
       UpdateSpaceRemaining(lRTBand);
@@ -6721,7 +6929,7 @@ var
   procedure ShowDataFooterBand(const ADsgnBand: TFPReportCustomDataFooterBand);
   begin
     CommonRuntimeBandProcessing(ADsgnBand);
-    if lRTBand.Visible then
+    if lRTBand.EvaluateVisibility then
     begin
       UpdateSpaceRemaining(lRTBand);
       if NoSpaceRemaining then
@@ -6939,7 +7147,9 @@ begin
               { group header }
               if lDsgnBand is TFPReportCustomGroupHeaderBand then
               begin
+                // Writeln('Found group with expr: ',TFPReportCustomGroupHeaderBand(lDsgnBand).GroupCondition);
                 s := TFPReportCustomGroupHeaderBand(lDsgnBand).Evaluate;
+                // Writeln('Group new ? "',lLastGroupCondition,'" <> "', s,'"');
                 if (lLastGroupCondition <> s) then
                 begin
                   lNewGroupHeader := True;
@@ -6969,8 +7179,8 @@ begin
                   ClearDataBandLastTextValues(lLastDsgnDataBand);
 
                 CommonRuntimeBandProcessing(lDsgnBand);
-                lLastGroupCondition := TFPReportGroupHeaderBand(lRTBand).GroupCondition;
-                if lDsgnBand.Visible = False then
+                lLastGroupCondition := TFPReportGroupHeaderBand(lRTBand).GroupConditionValue;
+                if lDsgnBand.EvaluateVisibility = False then
                 begin
                   lRTPage.RemoveChild(lRTBand);
                   lRTBand.Free;
@@ -7732,113 +7942,6 @@ begin
   // Do nothing
 end;
 
-function TFPReportCustomBand.ExpandMacro(const s: String; const AIsExpr: boolean): TFPReportString;
-var
-  pstart: integer;
-  pend: integer;
-  len: integer;
-  m: string;  // macro
-  mv: string; // macro value
-  r: string;
-  lFoundMacroInMacro: boolean;
-
-  function EvaluateExpression(const AExpr: String): String;
-  var
-    lExpr: TFPExpressionParser;
-  begin
-    Result := '';
-    lExpr := Page.Report.FExpr;
-    lExpr.Expression := AExpr;
-    case lExpr.ResultType of
-      rtString  : Result := lExpr.AsString;
-      rtInteger : Result := IntToStr(lExpr.AsInteger);
-      rtFloat   : Result := FloatToStr(lExpr.AsFloat);
-      rtBoolean : Result := BoolToStr(lExpr.AsBoolean, True);
-      rtDateTime : Result := FormatDateTime('yyyy-mm-dd', lExpr.AsDateTime);
-    end;
-  end;
-
-begin
-  r := s;
-  lFoundMacroInMacro := False;
-  pstart := Pos('[', r);
-  while (pstart > 0) or lFoundMacroInMacro do
-  begin
-    if lFoundMacroInMacro then
-    begin
-      pstart := Pos('[', r);
-      lFoundMacroInMacro := False;
-    end;
-    len := Length(r);
-    pend := pstart + 2;
-    while pend < len do
-    begin
-      if r[pend] = '[' then  // a macro inside a macro
-      begin
-        lFoundMacroInMacro := True;
-        pstart := pend;
-      end;
-      if r[pend] = ']' then
-        break
-      else
-        inc(pend);
-    end;
-
-    m := Copy(r, pstart, (pend-pstart)+1);
-    if (m = '[PAGECOUNT]') and Page.Report.TwoPass and Page.Report.IsFirstPass then
-    begin
-      // replace macro with a non-marco marker. We'll replace the marker in the second pass of the report.
-      r := StringReplace(r, m, cPageCountMarker, [rfReplaceAll, rfIgnoreCase]);
-      // look for more macros
-      pstart := Pos('[', r);
-      Continue;
-    end;
-
-    len := Length(m);
-    try
-      if Assigned(GetData) then
-      begin
-        try
-          mv := GetData.FieldValues[Copy(m, 2, len-2)];
-        except
-          on e: EVariantTypeCastError do  // maybe we have an expression not data field
-          begin
-            mv := EvaluateExpression(Copy(m, 2, len-2));
-          end;
-        end;
-      end
-      else
-      begin // No Data assigned, but maybe we have an expression
-        mv := EvaluateExpression(Copy(m, 2, len-2));
-      end;
-    except
-      on e: EVariantTypeCastError do    // ReportData.OnGetValue did not handle all macros, so handle this gracefully
-        mv := SErrUnknownMacro+': '+copy(m,2,len-2);
-      on e: EExprParser do
-        mv := SErrUnknownMacro+': '+copy(m,2,len-2);
-    end;
-    r := StringReplace(r, m, mv, [rfReplaceAll, rfIgnoreCase]);
-    // look for more macros
-    pstart := PosEx('[', r,PStart+Length(mv));
-  end;
-  { This extra check is mostly for ReportGroupHeader expression processing }
-  if (pstart = 0) and Assigned(GetData) and AIsExpr then
-  begin
-    try
-      r := EvaluateExpression(r);
-    except
-      on E: Exception do
-      begin
-        {$ifdef gdebug}
-        writeln('ERROR in expression: ', E.Message);
-        {$endif}
-        // do nothing - move on as we probably handled the expression a bit earlier in this code
-      end;
-    end;
-  end;
-  Result := r;
-end;
-
 procedure TFPReportCustomBand.SetParent(const AValue: TFPReportElement);
 begin
   if not ((AValue = nil) or (AValue is TFPReportCustomPage)) then
@@ -7853,6 +7956,7 @@ begin
 end;
 
 procedure TFPReportCustomBand.PrepareObjects;
+
 var
   lRTPage: TFPReportCustomPage;
   i: integer;
@@ -7863,6 +7967,7 @@ var
   c: integer;
   n: TFPExprNode;
   nIdx: integer;
+
 begin
   i := Page.Report.FRTCurPageIdx;
   if Assigned(Page.Report.RTObjects[i]) then
@@ -7876,11 +7981,7 @@ begin
   inherited PrepareObjects;
 
   if self is TFPReportGroupHeaderBand then
-  begin
-    s := TFPReportGroupHeaderBand(Page.Report.FRTCurBand).GroupCondition;
-    s := ExpandMacro(s, True);
-    TFPReportCustomGroupHeaderBand(Page.Report.FRTCurBand).GroupCondition := s;
-  end;
+    TFPReportGroupHeaderBand(Page.Report.FRTCurBand).CalcGroupConditionValue;
 
   if Assigned(FChildren) then
   begin