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

Currency field display problem

I think the TppDisplayFormat.ReplaceCurrencySymbol method was introduced in 18.02 or 18.03 and it's gives incorrect results on our customers' legacy reports. We have customers that would have used the DisplayFormat editor to add a mask such as

"$"#,##0.00;("$"#,##0.00)

Note the double quotes around the currency symbol, which must have been put there by some previous incarnation of the DisplayFormat editor (I note it doesn't do that now). Our users would never know why one would put the symbol in double quotes so they would never have done this themselves.

In the 18.01 version of TppDisplayFormat.Format that didn't use ReplaceCurrencySymbol, the lsFormatStr that is returned when a UK currency symbol in set in ppFormatSettings is

""£""#,##0.00;(""£""#,##0.00)

with 18.03 (and 19) it's

"$"#,##0.00;("$"#,##0.00)

I'm aware that this introduces a conundrum because the double quotes are now acting as escape characters and how can you change the code to accommodate legacy formatting strings? But we are about to release an upgrade to our app to hundreds of companies and we can't expect them all to go in and start editing their reports. They won't even notice until "their" customers start wonder why some figures on quotes and invoices are in dollars! :)

Comments

  • Hi Paul,

    The TppDisplayFormat class handles formatting (ppDisplayForm.pas). You can descend from it and customize it. You can even customize the formats displayed by the designer format dialog. The initialization section at the bottom sets up the class reference, you can use that code to register your replacement.

    RB uses Delphi's FormatFloat and according to the Delphi help 'characters enclosed in quotes are output as such and do not affect formatting.' RB never included or added quotes to the currency formats.



    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
  • Hello Nard,

    I understand how it all works, but the change you introduced with 18.03 breaks existing reports if the currency symbol in the DisplayFormat string is in quotes. I understand why you have done it, but there is no way the quotes are there because our users put them there: it must have happened as a result of the Displayformat dialog in previous versions of RB. We've found lots of reports in tests where this goes wrong.

    I can code around it in the RAP implementation that I already have to set Delphi's FormatSettings and RB's ppFormatSettings to the correct locale for the report (US, UK, French etc) , but I too will run the risk of having to ignore the DisplayFormat string for currency fields and replace it with my own CurrencyManager's CurrencyFormattingString.

    Before 18.03 all I had to do in a RAP pass thru was

    CurrencyManager.SetLocaleGlobals(aCurrency);

    ...which effectively retrievea the correct windows settings for a locale and then applies this to Delphi's FormatSettings and RB's ppFormatSettings .

    Now, I'l have to do something like below (a recursive method) to check if a report's object has a DisplayFormat string set and just replace it. It's not ideal. So if you have any other thoughts, it would be appreciated. Thanks, Paul

    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
    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

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

    end;

    end;

    end;
  • edited March 2018
    OK, I've opted in the above routine to require double double-quotes in the DisplayFormat string if a currency symbol is to be hardcoded:

    // harcoded symbols to require double double-quotes, e.g. ""$""
    // "$" is replaced with $
    if lDataType = dtCurrency then
    TppCustomTextAccess(lObject).DisplayFormat :=
    StringReplace(TppCustomTextAccess(lObject).DisplayFormat, '"$"', '$', [rfReplaceAll]);

    Seems to be the best compromise, for now.
  • Hi Paul,

    I just emailed you an example project I created. The example contains a TmyRBDisplayFormat plug-in that implements the old RB 18.02 logic.

    To use the plug-in, simply add myDisplayFormat to the 'uses'.



    Best regards,

    Nard Moseley
    Digital Metaphors
    www.digital-metaphors.com
Sign In or Register to comment.