Finding components within a report
Hello
What is the best way to find a specific component in a report at runtime?
I did the function below which finds a component in the main band of a
single report, and do does not really support subreports
FUNCTION FindReportComponent(CONST objReport:TppReport;CONST
strUserName:String;CONST bRaiseException:Boolean=True):TppComponent;
VAR liBand:Integer;
liObject:Integer;
lObject:TppComponent;
BEGIN
Result:=NIL;
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
IF SameText(lObject.UserName,strUserName) THEN
BEGIN
Result:=lObject AS TppComponent;
Exit;
END; {IF - Chart has been found - Exit}
END; {FOR - Loop through all objects in the band}
IF Result=NIL THEN
BEGIN
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
CodeSite.SendString('Object Name ',lObject.UserName);
END; {FOR - Loop through all objects in the band}
RAISE ESTCException.Create('Component Named '+strUserName+' Not found
in report : '+objReport.Template.FileName);
END
END;
So my colleague then did the version below, which is the opposite!
FUNCTION FindReportComponentNEW(CONST objReport:TppCustomReport;CONST
strUserName:String;CONST bRaiseException:Boolean=True):TppComponent;
VAR liBand:Integer;
liObject:Integer;
lObject:TppComponent;
BEGIN
Result:=NIL;
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
IF SameText(lObject.UserName,strUserName) THEN
BEGIN
Result:=lObject AS TppComponent;
Exit;
END; {IF - Chart has been found - Exit}
if lObject is TppSubReport then
begin
Result := FindReportComponentNEW(TppSubReport(lObject).Report,
strUserName, bRaiseException);
if Result <> nil then
Exit;
end;
END; {FOR - Loop through all objects in the band}
IF Result=NIL THEN
BEGIN
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
CodeSite.SendString('Object Name ',lObject.UserName);
END; {FOR - Loop through all objects in the band}
if bRaiseException then
RAISE ESTCException.Create('Component Named '+strUserName+' Not found
in report : '+objReport.Template.FileName);
END
END;
The version above then does not find components that are in my main report
Cheers
Paul
What is the best way to find a specific component in a report at runtime?
I did the function below which finds a component in the main band of a
single report, and do does not really support subreports
FUNCTION FindReportComponent(CONST objReport:TppReport;CONST
strUserName:String;CONST bRaiseException:Boolean=True):TppComponent;
VAR liBand:Integer;
liObject:Integer;
lObject:TppComponent;
BEGIN
Result:=NIL;
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
IF SameText(lObject.UserName,strUserName) THEN
BEGIN
Result:=lObject AS TppComponent;
Exit;
END; {IF - Chart has been found - Exit}
END; {FOR - Loop through all objects in the band}
IF Result=NIL THEN
BEGIN
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
CodeSite.SendString('Object Name ',lObject.UserName);
END; {FOR - Loop through all objects in the band}
RAISE ESTCException.Create('Component Named '+strUserName+' Not found
in report : '+objReport.Template.FileName);
END
END;
So my colleague then did the version below, which is the opposite!
FUNCTION FindReportComponentNEW(CONST objReport:TppCustomReport;CONST
strUserName:String;CONST bRaiseException:Boolean=True):TppComponent;
VAR liBand:Integer;
liObject:Integer;
lObject:TppComponent;
BEGIN
Result:=NIL;
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
IF SameText(lObject.UserName,strUserName) THEN
BEGIN
Result:=lObject AS TppComponent;
Exit;
END; {IF - Chart has been found - Exit}
if lObject is TppSubReport then
begin
Result := FindReportComponentNEW(TppSubReport(lObject).Report,
strUserName, bRaiseException);
if Result <> nil then
Exit;
end;
END; {FOR - Loop through all objects in the band}
IF Result=NIL THEN
BEGIN
FOR liBand:=0 TO objReport.BandCount-1 DO
FOR liObject:=0 TO objReport.Bands[liBand].ObjectCount-1 DO
BEGIN
lObject:=objReport.Bands[liBand].Objects[liObject];
CodeSite.SendString('Object Name ',lObject.UserName);
END; {FOR - Loop through all objects in the band}
if bRaiseException then
RAISE ESTCException.Create('Component Named '+strUserName+' Not found
in report : '+objReport.Template.FileName);
END
END;
The version above then does not find components that are in my main report
Cheers
Paul
This discussion has been closed.
Comments
You can recursively loop through each subreport if you encounter one. For
instance inside your second nested "for" loop...
if lObject is TppSubreport then
FindReportComponent(TppSubreport(lObject).Report, ...
You will need to change the signature of the FindReportComponent to (const
objReport: TppCustomReport; ...)
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
FindReportComponent and FindReportComponentNew, I think you mean its best to
use the first one
Sorry, I did not see the second method below. The second method is correct
but note that this will only find the first occurance of the component you
are looking for. If, in the initial loop, it encounters a subreport and
inside the subreport it finds a TppComponent with the correct username it
will exit out of all the for loops as coded.
--
Regards,
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com