对于您可以在代码中计算的任何内容、数组值列表、聚合或函数计算结果,我更喜欢使用TfrxUserDataSet
并实现TfrxReport.OnGetvalue
事件。
尽管最初可能会令人困惑,但用户数据集只是声明了一个数据集名称,以及通过该数据集名称可用的字段列表,并使用触发的事件让您“导航”(第一条,下一条记录)并声明您何时'已达到计算数据的末尾。这允许您构建一个“生成器”,或者只是一个用于计算的普通虚拟数据提供者逻辑集。
这是我的 OnGetValue 事件的样子:
procedure TfrmReport.frxReportGetValue(const VarName: string; var Value: Variant);
begin
Value := GetReportValue(VarName);
end;
// INPUT: VarName = '(<GlobalArea."hdReportTitle">)'
// OUTPUT: tableName = 'GlobalArea', fieldName = 'hdReportTitle'
function ParseVar(const VarName:String; var tableName,fieldName:String; var ParenFlag:Boolean):Boolean;
var
paVarName:String;
angleBracketFlag:Boolean;
dotPos:Integer;
fieldQuoteFlag:Boolean;
procedure RemoveOuter(var str:String; initialChar,finalChar:Char; var flag);
var
n:Integer;
begin
n := Length(str);
if n>2 then begin
ParenFlag := (str[1]=initialChar) and (str[n]=finalChar);
if ParenFlag then begin
str := Copy(str,2,n-2);
end;
end;
end;
begin
result := false;
fieldQuoteFlag := false;
paVarName := SysUtils.Trim(VarName);
ParenFlag := false;
tableName := '';
fieldName := '';
RemoveOuter(paVarName, '(',')',parenFlag);
RemoveOuter(paVarName,'<','>',angleBracketFlag);
dotPos := Pos('.',paVarName);
if dotPos >0 then begin
tableName := Copy(paVarName,1,dotPos-1);
fieldName := Copy(paVarName,dotPos+1,Length(paVarName));
RemoveOuter(fieldName, '"','"',fieldQuoteFlag);
result := true;
end else begin
tableName := '';
fieldName := paVarName;
end;
end;
function TfrmProfitAnalysisReport.GetReportValue(const VarName:String):Variant;
var
tableName:String;
fieldName:String;
parenFlag:Boolean;
begin
ParseVar(VarName,tableName,fieldName,parenFlag);
result := NULL;
{ Global Area - Header Values }
if sameText(tableName,'GlobalArea') then begin
if fieldName='hdReportTitle' then
result := GetTitle; { A function that calculates a title for the report }
else if fieldName='hdReportSubtitle' then
result := 'Report for Customer XYZ'
else if fieldName='....' then begin
...
end;
if Variants.VarIsNull( result) then
result := '?'+fieldName+'?';
end;