Home General
New Blog Posts: Merging Reports - Part 1 and Part 2

Finding components within a report

edited October 2005 in General
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

Comments

  • edited October 2005
    Hi Paul,

    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

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2005
    Which is the best one to use then Nico - there are 2 functions there -
    FindReportComponent and FindReportComponentNew, I think you mean its best to
    use the first one

  • edited October 2005
    Hi Paul,

    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

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
This discussion has been closed.