Iterating a dataset in an OnCalc event
Hi,
I want to loop through all values in a RAP dataset linked to the main
dataset and populate the result with all recoords of a specific field,
in this case telephone numbers. RAP seems to know about EOF but it
roesn't recognise Next. So how can I do this.
Or is there another way without even using RAP.
Thanks,
Ken
I want to loop through all values in a RAP dataset linked to the main
dataset and populate the result with all recoords of a specific field,
in this case telephone numbers. RAP seems to know about EOF but it
roesn't recognise Next. So how can I do this.
Or is there another way without even using RAP.
Thanks,
Ken
This discussion has been closed.
Comments
I wrote my own RAP class for this:
//MMWIN:CLASSCOPY
unit _MM_Copy_Buffer_;
interface
type
TnavTppDataPipelineRTTI = class(TraTppDBPipelineRTTI)
public
class procedure GetPropList(aClass : TClass; aPropList : TraPropList);
override;
class function GetPropRec(aClass : TClass; const aPropName : String;
var aPropRec : TraPropRec) : Boolean; override;
class function GetParams(const aMethodName : String) : TraParamList;
override;
class function CallMethod(aObject : TObject; const aMethodName :
String; aParams : TraParamList; aGet : Boolean) : Boolean; override;
class function GetPropValue(aObject : TObject; const aPropName :
String; var aValue) : Boolean; override;
class function RefClass : TClass; override;
class function SetPropValue(aObject : TObject; const aPropName :
String; var aValue) : Boolean; override;
end;
implementation
{ TnavTppDataPipelineRTTI }
class function TnavTppDataPipelineRTTI.CallMethod(aObject : TObject;
const aMethodName : String; aParams : TraParamList; aGet : Boolean) :
Boolean;
var
lPipeline : TppDBPipeline;
begin
Result := True;
lPipeline := TppDBPipeline(aObject);
if ppEqual(aMethodName, 'First') then
begin
TppDataPipelineAccess(lPipeline).First;
end
else
if ppEqual(aMethodName, 'Last') then
begin
lPipeline.Last;
end
else
if ppEqual(aMethodName, 'Next') then
begin
TppDataPipelineAccess(lPipeline).TraverseBy(1);
end
else
if ppEqual(aMethodName, 'Prior') then
begin
TppDataPipelineAccess(lPipeline).TraverseBy(-1);
end
else
Result := inherited CallMethod(aObject, aMethodName, aParams, aGet);
end;
class function TnavTppDataPipelineRTTI.GetParams(const aMethodName :
String) : TraParamList;
begin
Result := inherited GetParams(aMethodName);
end;
class procedure TnavTppDataPipelineRTTI.GetPropList(aClass : TClass;
aPropList : TraPropList);
begin
inherited GetPropList(aClass, aPropList);
{add methods}
aPropList.AddMethod('First');
aPropList.AddMethod('Last');
aPropList.AddMethod('Next');
aPropList.AddMethod('Prior');
end;
class function TnavTppDataPipelineRTTI.GetPropRec(aClass : TClass; const
aPropName : String; var aPropRec : TraPropRec) : Boolean;
begin
Result := True;
if ppEqual(aPropName, 'First') then
MethodToRec(aPropName, False, aPropRec) else
if ppEqual(aPropName, 'Last') then
MethodToRec(aPropName, False, aPropRec) else
if ppEqual(aPropName, 'Next') then
MethodToRec(aPropName, False, aPropRec) else
if ppEqual(aPropName, 'Prior') then
MethodToRec(aPropName, False, aPropRec) else
Result := inherited GetPropRec(aClass, aPropName, aPropRec);
end;
class function TnavTppDataPipelineRTTI.GetPropValue(aObject : TObject;
const aPropName : String; var aValue) : Boolean;
begin
Result := inherited GetPropValue(aObject, aPropName, aValue);
end;
class function TnavTppDataPipelineRTTI.RefClass : TClass;
begin
Result := inherited RefClass;
end;
class function TnavTppDataPipelineRTTI.SetPropValue(aObject : TObject;
const aPropName : String; var aValue) : Boolean;
begin
Result := inherited SetPropValue(aObject, aPropName, aValue);
end;
initialization
raUnregisterRTTI(TraTppDBPipelineRTTI);
raRegisterRTTI(TnavTppDataPipelineRTTI);
finalization
raUnregisterRTTI(TraTppDBPipelineRTTI);
raRegisterRTTI(TnavTppDataPipelineRTTI);
end.
The solution Paul gave is a great example of extending the RAP RTTI.
It is also possible to create a RAP pass-thru function to perform the
same task. You could create a pass-thru function named
PipelineNext(aPipeline), which takes the DataPipeline as a parameter and
then calls .Next in Delphi. See the RAP demos for examples of pass-thru
functions.
I'm however a bit unclear about what you are trying to accomplish. Do
you wish to populate a TppVariable with all the phone numbers in the
dataset? If you would like to display all records in a field, why not
just connect that dataset to a subreport and have it iterate through the
dataset for you?
Nico Cizik
Digital Metaphors
http://www.digital-metaphors.com
That is what I have now done.
Ken
Yes, I created my RAP RTTI class because I wanted to get info and store
it in a structure BEFORE the report prints so that I could make
decisions about whether to display groups etc in advance.
Excel the contents of the subreport are not included. My subreport is a
child report. Is there a way to do this?
For XlsReport all elements are exported.
For XlsData the default behavior is main report detail elements are
exported. Use the File | Print To File Setup dialog to specify which bands
and component to export. For a subreport, access the workspace for the
childreport and use the File | Print To File Setup dialog from there.
Check out the RBuilder Help topics for TppXlsReportDevice and
TppXlsDataDevice for more details on using these devices.
Best regards,
-
Nard Moseley
Digital Metaphors
www.digital-metaphors.com
Best regards,
Nard Moseley
Digital Metaphors
www.digital-metaphors.com