diff --git a/components/lazreport/source/lazreport.lpk b/components/lazreport/source/lazreport.lpk
index 26bd9b8ac1..b735082f58 100644
--- a/components/lazreport/source/lazreport.lpk
+++ b/components/lazreport/source/lazreport.lpk
@@ -5,17 +5,17 @@
-
+
-
-
-
+
+
+
+
+
-
diff --git a/components/lazreport/source/lr_class.pas b/components/lazreport/source/lr_class.pas
index ddda4501b9..23551c81c4 100644
--- a/components/lazreport/source/lr_class.pas
+++ b/components/lazreport/source/lr_class.pas
@@ -6004,6 +6004,7 @@ var
DetailCount : Integer;
BooksBkUp : array of TBookRecord;
CurGroupValue : variant;
+ BookPrev : pointer;
procedure AddToStack(b: TfrBand);
begin
@@ -6142,43 +6143,55 @@ var
else
ShowStack;
- b.DataSet.Next;
-
if (Level = 1) and HasGroups then
begin
- b1 := Bands[btGroupHeader];
- while b1 <> nil do
- begin
- curGroupValue := frParser.Calc(b1.GroupCondition);
- {$IFDEF DebugLR}
- DebugLn('%sGroupCondition=%s curGroupValue=%s LastGroupValue=%s',
- [sspc,b1.GroupCondition,string(b1.LastGroupValue),string(curGroupValue)]);
- {$ENDIF}
- if (curGroupValue <> b1.LastGroupValue) or
- b.Dataset.Eof then
+ // get a bookmark to current record it will be used in case
+ // a group change is detected and there are remaining group
+ // footers.
+ BookPrev := b.DataSet.GetBookMark;
+ try
+ b.DataSet.Next;
+ b1 := Bands[btGroupHeader];
+ while b1 <> nil do
begin
- ShowBand(b.FooterBand);
- b2 := Bands[btGroupHeader].LastBand;
- while b2 <> b1 do
+ curGroupValue := frParser.Calc(b1.GroupCondition);
+ {$IFDEF DebugLR}
+ DebugLn('%sGroupCondition=%s LastGroupValue=%s curGroupValue=%s',
+ [sspc,b1.GroupCondition,string(b1.LastGroupValue),string(curGroupValue)]);
+ {$ENDIF}
+ if (curGroupValue <> b1.LastGroupValue) or
+ b.Dataset.Eof then
begin
- ShowBand(b2.FooterBand);
- b2.Positions[psLocal] := 0;
- b2 := b2.Prev;
+ // next bands should be printed on the previous record context
+ b.DataSet.GotoBookMark(BookPrev);
+ ShowBand(b.FooterBand);
+ b2 := Bands[btGroupHeader].LastBand;
+ while b2 <> b1 do
+ begin
+ ShowBand(b2.FooterBand);
+ b2.Positions[psLocal] := 0;
+ b2 := b2.Prev;
+ end;
+ ShowBand(b1.FooterBand);
+ // advance to the actual current record
+ b.DataSet.Next;
+ if not b.Dataset.Eof then
+ begin
+ if b1.NewPageAfter then NewPage;
+ InitGroups(b1);
+ ShowBand(b.HeaderBand);
+ b.Positions[psLocal] := 0;
+ end;
+ b.ResetLastValues;
+ break;
end;
- ShowBand(b1.FooterBand);
- if not b.DataSet.Eof then
- begin
- if b1.NewPageAfter then NewPage;
- InitGroups(b1);
- ShowBand(b.HeaderBand);
- b.Positions[psLocal] := 0;
- end;
- b.ResetLastValues;
- break;
+ b1 := b1.Next;
end;
- b1 := b1.Next;
+ finally
+ b.DataSet.FreeBookMark(BookPrev);
end;
- end;
+ end else
+ b.DataSet.Next;
if Mode = pmBuildList then
AddRecord(b, rtNext)
diff --git a/components/lazreport/source/lr_dbset.pas b/components/lazreport/source/lr_dbset.pas
index b02c65428f..9ab9a5666c 100644
--- a/components/lazreport/source/lr_dbset.pas
+++ b/components/lazreport/source/lr_dbset.pas
@@ -31,6 +31,7 @@ type
FOnOpen, FOnClose: TNotifyEvent;
FBookmark: TfrBookmark;
FEof: Boolean;
+ function GetSafeDataset: TDataSet;
procedure SetDataSet(Value: TDataSet);
procedure SetDataSource(Value: TDataSource);
protected
@@ -56,7 +57,7 @@ type
published
property CloseDataSource: Boolean read FCloseDataSource write FCloseDataSource default False;
- property DataSet: TDataSet read FDataSet write SetDataSet;
+ property DataSet: TDataSet read GetSafeDataset write SetDataSet;
property DataSource: TDataSource read FDataSource write SetDataSource;
property OpenDataSource: Boolean read FOpenDataSource write FOpenDataSource default True;
property RangeBegin;
@@ -99,6 +100,16 @@ begin
FDataSource := nil;
end;
+function TfrDBDataSet.GetSafeDataset: TDataSet;
+begin
+ if FDataSource<>nil then
+ Result := FDataSource.DataSet
+ else
+ Result := nil;
+ if Result=nil then
+ Result := FDataset;
+end;
+
procedure TfrDBDataSet.SetDataSource(Value: TDataSource);
begin
FDataSource := Value;
@@ -123,32 +134,32 @@ function TfrDBDataSet.GetBookMark: Pointer;
begin
Result:=inherited GetBookMark;
- if Assigned(fDataSet) then
- Result:=fDataSet.GetBookmark;
+ if Assigned(Dataset) then
+ Result:=Dataset.GetBookmark;
end;
procedure TfrDBDataSet.GotoBookMark(BM: Pointer);
begin
- if Assigned(fDataSet) then
- fDataSet.GotoBookmark(BM);
+ if Assigned(Dataset) then
+ Dataset.GotoBookmark(BM);
end;
procedure TfrDBDataSet.FreeBookMark(BM: Pointer);
begin
- if Assigned(fDataSet) and Assigned(BM) then
- fDataSet.FreeBookmark(BM);
+ if Assigned(Dataset) and Assigned(BM) then
+ Dataset.FreeBookmark(BM);
end;
procedure TfrDBDataSet.DisableControls;
begin
- if Assigned(fDataSet) then
- fDataSet.DisableControls;
+ if Assigned(Dataset) then
+ Dataset.DisableControls;
end;
procedure TfrDBDataSet.EnableControls;
begin
- if Assigned(fDataSet) then
- fDataSet.EnableControls;
+ if Assigned(Dataset) then
+ Dataset.EnableControls;
end;
procedure TfrDBDataSet.Init;