注意:需要在控制报表的BCB程序头文件.h中加上类TfrxDBDataSet的头文件 #include "frxCustomDBRTTI.hpp" ,在.cpp文件的头部加上#pragma link "frxCustomDBRTTI"。如果不加则会报没有定义类型TfrxDBDataSet的错误。
合并单元格实现原理:
在报表开始前先计算出需要合并的行的高度数组,在打印前根据这个高度数组设置对应打印对象的高度和显示。
实现方法如下:
设置Page1的OnBeforePrint事件,MasterData1的OnBeforePrint事件,代码如下:
Var
iRowCount:Integer;
AryStatHeight:Array of Extended;
AryRoadHeight:Array of Extended;
AryStation:Array of String;
AryLine:Array of String;
procedure Page1OnBeforePrint(Sender: TfrxComponent);
var
i,j,iRepeat: Integer;
sLastValue,sCurValue: String;
MyDataSet:TfrxDBDataSet;
begin
MyDataSet := TfrxDBDataSet(Report.GetDataSet('frxdbdtst1'));
iRowCount := MyDataSet.RecordCount;
//逐记录取值,同一个入口站的则记录要合并的单元格
SetLength(AryStatHeight,iRowCount);
SetLength(AryStation,iRowCount);
MyDataSet.First;
sCurValue := '';
j := 1;
for i := 0 to iRowCount - 1 do
begin
sLastValue := sCurValue;
sCurValue := MyDataSet.DataSet.FieldByName('EnRoadID').AsString + MyDataSet.DataSet.FieldByName('EnStationID').AsString;
//若有重复单元格,则标记当前重复单元格的高度为0,第一个重复单元格的高度为重复单元格高度的和
if (sLastValue <> '') and (sLastValue = sCurValue)
and ((i + 36 - 31) mod 36<>0) then //
begin
iRepeat := iRepeat + 1;
AryStatHeight[i] := 0;
AryStatHeight[i - iRepeat] := MasterData1.Height * (iRepeat + 1);
end
else
begin
iRepeat := 0;
AryStatHeight[i] := MasterData1.Height;
end;
//若有重复单元格,则标记该重复单元格的行号为空
if (sLastValue <> '') and (sLastValue = sCurValue) then
begin
AryStation[i] := '';
end
else
begin
AryStation[i] := IntToStr(j);
j := j + 1;
end;
MyDataSet.Next;
end;
//逐记录取值,同个入口路段的则记录要合并的单元格
SetLength(AryRoadHeight,iRowCount);
MyDataSet.First;
sCurValue := '';
for i := 0 to iRowCount - 1 do
begin
sLastValue := sCurValue;
sCurValue := MyDataSet.DataSet.FieldByName('EnRoadID').AsString;
//若有重复单元格,则标记当前重复单元格的高度为0,第一个重复单元格的高度为重复单元格高度的和
if (sLastValue <> '') and (sLastValue = sCurValue) and ((i + 36 - 31) mod 36<>0) then
begin
iRepeat := iRepeat + 1;
AryRoadHeight[i] := 0;
AryRoadHeight[i - iRepeat] := MasterData1.Height * (iRepeat + 1);
end
else
begin
iRepeat := 0;
AryRoadHeight[i] := MasterData1.Height;
end;
MyDataSet.Next;
end;
//重新控制报表显示行号
SetLength(AryLine,iRowCount);
MyDataSet.First;
sCurValue := '';
j := 1;
for i := 0 to iRowCount - 1 do
begin
sLastValue := sCurValue;
sCurValue := MyDataSet.DataSet.FieldByName('EnRoadID').AsString;
//若有重复单元格,则标记该重复单元格的行号为空,非重复单元格则行号递增
if (sLastValue <> '') and (sLastValue = sCurValue) then
begin
AryLine[i] := '';
end
else
begin
AryLine[i] := IntToStr(j);
j := j + 1;
end;
MyDataSet.Next;
end;
end;
procedure MasterData1OnBeforePrint(Sender: TfrxComponent);
begin
//同一入口站合并
if AryStatHeight[<Line#> - 1] = 0 then
begin
Memo56.Visible := False;
Memo57.Visible := False;
Memo59.Visible := False;
end
else
begin
Memo56.Visible := True;
Memo56.Height := AryStatHeight[<Line#> - 1];
Memo57.Visible := True;
Memo57.Height := AryStatHeight[<Line#> - 1];
Memo59.Visible := True;
Memo59.Height := AryStatHeight[<Line#> - 1];
end;
//同一入口路段合并
if AryRoadHeight[<Line#> - 1] = 0 then
begin
Memo48.Visible := False;
Memo49.Visible := False;
Memo61.Visible := False;
Memo62.Visible := False;
Memo1.Visible := False;
Memo2.Visible := False;
end
else
begin
Memo48.Visible := True;
Memo48.Height := AryRoadHeight[<Line#> - 1];
Memo49.Visible := True;
Memo49.Height := AryRoadHeight[<Line#> - 1];
Memo61.Visible := True;
Memo61.Height := AryRoadHeight[<Line#> - 1];
Memo62.Visible := True;
Memo62.Height := AryRoadHeight[<Line#> - 1];
Memo1.Visible := True;
Memo1.Height := AryRoadHeight[<Line#> - 1];
Memo2.Visible := True;
Memo2.Height := AryRoadHeight[<Line#> - 1];
end;
if AryStation[<Line#> - 1] = '' then
begin
Memo56.Font.Color:=clWhite;
Memo57.Font.Color:=clWhite;
Memo59.Font.Color:=clWhite;
end
else
begin
Memo56.Font.Color:=clBlack;
Memo57.Font.Color:=clBlack;
Memo59.Font.Color:=clBlack;
end;
if AryLine[<Line#> - 1] = '' then
begin
Memo48.Memo.Clear();
Memo49.Font.Color:=clWhite;
Memo61.Font.Color:=clWhite;
Memo62.Font.Color:=clWhite;
Memo1.Font.Color:=clWhite;
Memo2.Font.Color:=clWhite;
end
else
begin
Memo48.Memo.Clear();
Memo48.Memo.Add(AryLine[<Line#> - 1]);
Memo49.Font.Color:=clBlack;
Memo61.Font.Color:=clBlack;
Memo62.Font.Color:=clBlack;
Memo1.Font.Color:=clBlack;
Memo2.Font.Color:=clBlack;
end;
end;
begin
end.
流程:
第一步.准备好要合并单元格的报表;
第二步.双击事件的‘OneBeforePrint’对应CODE代码(确保完成第三步,否则代码无法生效,完成后直接预览),首先是Page1的事件设置, 其次是MasterDate1的事件设置;
第三步.在CODE页写入代码。