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

Using the DisplayFormat of the assigned TppField

edited October 2012 in General
Hello,

datasets in my application have DisplayFormats assigned to several fields,
depending on the settings of the user.
In my RB templates I have DisplayFormats set to all appropriate
DBText-objects.

The problem is, that once the user changes the settings and the
DisplayFormats within the application become different, my RB templates
don't know anything about the changes and use "old" DisplayFormats, until
the user changes the template manualy.

This is not user friendly, so I'm looking for a way to automatically use the
DisplayFormats of the application in RB templates.
I've tried to set DisplayFormats of the pipeline fields, but this seems not
to have any effect on the templates.

Is there a way to accomplish that?

Best regards,
Mark

Comments

  • edited October 2012
    Hi Mark,

    The DisplayFormat property of the TppField does not carry over to any
    data aware components on a report. It is specifically used to define
    the date format used when searching date fields (autosearch).

    Once the template is loaded, you will need to go through each data aware
    component and update its DisplayFormat property in order to reflect any
    changes that have been made by your user.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2012
    To cope with MultiCurrency in our app I have a RAP procedure called
    FormatCurrencyFields that I get reports to call in the BeforePrint event
    for the report:


    procedure TFormatCurrencyFields.ExecuteFunction(aParams : TraParamList);
    var lReport : TppCustomReport;
    lCurrency : Integer;
    begin
    GetParamValue(0, lReport);
    GetParamValue(1, lCurrency);


    TnxReportsManager.ReportBuilderEngine.SetNumberFormatsForWholeReport(lReport,
    lCurrency);
    end;

    class function TFormatCurrencyFields.GetSignature : String;
    begin
    result := 'procedure FormatCurrencyFields(aReport :
    TppCustomReport; aCurrency: integer);';
    end;


    Then SetNumberFormatsForWholeReport() gets implemented thus:

    procedure TrbReporting.SetNumberFormatsForWholeReport(aReport :
    TppCustomReport; aCurrency : Integer);
    var
    lBandIndex : Integer;
    lObjectIndex : Integer;
    lObject : TppComponent;
    lDataPipeline : TppDataPipeline;
    lDataField : String;
    lDataType : TppDataType;
    begin
    // for job based reports where currency is specific.
    // This routine is called by our RAP pass-thru class
    TFormatCurrencyFields
    // allowing a report to auto fix up its display settings for number
    fields with a single
    // call to FormatCurrencyFields, e.g. FormatCurrencyFields(Report,
    Invoice['JOBS.Currency']);

    for lBandIndex := 0 to aReport.BandCount - 1 do
    for lObjectIndex := 0 to aReport.Bands[lBandIndex].ObjectCount -
    1 do
    begin
    lObject := aReport.Bands[lBandIndex].Objects[lObjectIndex];

    if lObject is TppSubReport then
    begin

    SetNumberFormatsForWholeReport(TppSubReport(lObject).Report, aCurrency);
    continue;
    end;

    if (lObject is TppDBText) or (lObject.InheritsFrom(TppDBText)) or
    (lObject is TppVariable) then
    // only set if nothing assigned (default)
    // if TppCustomTextAccess(lObject).DisplayFormat = '' then
    begin

    lDataPipeline := TppDBText(lObject).DataPipeline;
    lDataField := TppDBText(lObject).DataField;

    if lObject is TppVariable then
    lDataType := TppVariable(lObject).DataType else
    lDataType := lDataPipeline.GetFieldDataType(lDataField);

    case lDataType of

    dtSingle,
    dtDouble,
    dtExtended : TppCustomTextAccess(lObject).DisplayFormat
    := CurrencyManager.CurrencySet[aCurrency].DecimalFomattingstring;

    dtCurrency : TppCustomTextAccess(lObject).DisplayFormat
    := CurrencyManager.CurrencySet[aCurrency].CurrencyFomattingstring;

    end;

    end;

    end;

    end;


  • edited October 2012
    Hi Nico,

    it was my fear that the reply would be similar to what you wrote...
    Don't you think that it would make sense to automatically use the
    DisplayFormat of the TppField (as long assigned) for the data aware
    component to which the field is assigned? This wouldn't do any harm to the
    current functionality, would it? But it sure would be an improvement and
    make it much easier to deal with such reports. Maybe an additional property
    of the pipeline to control this behaviour? Something like
    "ApplyDisplayFormatToDataAwareComponents"...

    Regards,
    Mark


  • edited October 2012
    Hi Paul,

    thank you for your reply and the example!
    I will take a look into it.

    Best regards,
    Mark

  • edited October 2012
    Hello,

    is there a difference between

    TppCustomTextAccess(lObject).DisplayFormat := ...
    and
    TppDBText(lObject).DisplayFormat := ...

    or better to say what is the difference?


  • edited October 2012
    Thanks for the feedback. We will consider it for a later release.

    Best Regards,

    Nico Cizik
    Digital Metaphors
    http://www.digital-metaphors.com
  • edited October 2012
    Ah, I forgot to mention that bit. TppCustomTextAccess is just a "cracker
    class" that promotes Displayformat to PUBLIC as it is only PROTECTED in
    the TppComponent that lObject is defined as:

    TppCustomTextAccess = class(TppCustomText)
    public
    property Displayformat;
    end;

    Seemed more elegant than doing local casts (TppDBText(lObject) or
    TppDBText(lObject) in the Displayformat :=...block) but you could do
    that too.


  • edited October 2012
    Ok, I see, thank you.

  • edited October 2012
    Hello,

    what do I have to pass as report-parameter form the ReportBeforePrint-event?
    First I tried it with "Report". This seemed to work, then it didn't work as
    myReport.BandCount appeared to be 0 for some reason, although I still see
    everything in the designer. Once this happened, I tried to use
    Report.MainReport as parameter, but since then I'm getting an access
    vialotaion when attemtpting to check the BandCount, although the report is
    not nil or something like that... Very weird.

    Do you habve any ideas?


  • edited October 2012
    Within RAP I am passing "Report" to my pass-thru procedure. Can't
    imagine why BandCount would be 0, I'm afraid - its always > 0 here.


  • edited October 2012
    It had worked here too first, then I've extended the parameters a bit etc.
    and then suddenly it stopped to work or better to say seems to be random...
    Sometimes I get an AV, sometimes a random integer value... I've put the
    whole procedure into a try-except block and once the error occurs, the
    report is showed in the preview as it was before - all the bands are there
    etc.

    Totaly clueless what is going on here.


  • edited October 2012
    How is your Execute procedure coded (copy it here)?

  • edited October 2012
    I was just about to copy&paste it here, when my eyes stopped at my local
    variables to store the parameter values. I remembered something and wanted
    to give it a try one last time and... it worked...

    First I had this:

    class function TraMySetDisplayFormat.GetSignature: String;
    begin
    Result := 'procedure mySetDisplayFormat(CurrentReport: TppCustomReport;
    CurrencyKind: smallint);';
    end;

    var
    lParamReport: TppCustomReport;
    lParamCurrencyKind: smallint;
    begin
    GetParamValue(0, lParamReport);
    GetParamValue(1, lParamCurrencyKind);
    ...

    This didn't work at all. I couldn't even access my procedure because the
    signature couldn't get compiled and the three was empty. Then I've changed
    smallint to integer and it worked, but I changed it in GetSignature only,
    i.e.

    class function TraMySetDisplayFormat.GetSignature: String;
    begin
    Result := 'procedure mySetDisplayFormat(CurrentReport: TppCustomReport;
    CurrencyKind: integer);';
    end;

    I'm sure it worked inbetween, but well, can't reproduce the cisrcumstances
    now.
    However, now that I was about to copy&paste my code here, I noticed that the
    local variable lParamCurrencyKind was still declared as smallint. I've
    changed it to integer too

    var
    lParamReport: TppCustomReport;
    lParamCurrencyKind: integer;
    begin
    GetParamValue(0, lParamReport);
    GetParamValue(1, lParamCurrencyKind);
    ...

    and it works! A very strange behavior with not avialable bands / corrupt
    Report-parameter as result, but well... It works now, so I can finally test
    my procedure.

    Thanks for your assistance!


This discussion has been closed.