cancel
Showing results for 
Search instead for 
Did you mean: 

Dynamically Change Number Format in Visual Studio

Former Member
0 Kudos

I did some searching on this site and google, and can't find a good solution to change number formatting in my Crystal Report.

This was the closest thing that I could find: ( ), but this seems to be to modify the report template itself, not the loaded report document.

I'd like my .rpt file to remain in tact. The report is financial and was initially designed for USD currency.

To handle other currencies, my solution is to add the Currency Code to the report. I also need to remove the currency symbol. I could do this in the designer. But the part that requires me to do this in code, is the need to dynamically change the thousand separator on-the-fly.

Swiss Franks show the thousand separator as 1'000.00

I'd really like to do something like this:

/* BEGIN CODE */

CrystalDecisions.CrystalReports.Engine.ReportDocument report;

report = new CrystalDecisions.CrystalReports.Engine.ReportDocument();

report.Load(rptFileName);

if (currencyCode == "CHF")

{

     foreach (CrystalDecisions.CrystalReports.Engine.ReportObject obj in report.ReportDefinition.ReportObjects){

          CrystalDecisions.CrystalReports.Engine.FieldObject fld = (CrystalDecisions.CrystalReports.Engine.FieldObject)obj;

          fld.FieldFormat.NumericFormat.ThousandSymbol = "'";

          //Unfortunately, ThousandSymbol doesn't exist in CrystalDecisions.CrystalReports.Engine.NumericFieldFormat.

          //Only in CrystalDecisions.ReportAppServer.ReportDefModel.NumericFieldFormat as specified in the thread link above;

          //...which I tried, but it doesn't seem to modify my ReportDocument to print the ThousandSymbol with the "'".

     }

}

report.SetDataSource(data);

report.ExportToDisk(ExportFormatType.PortableDocFormat, pdfFileName);

/* END CODE */

Is there a way to change the FieldFormat for the ReportDocument loaded in memory? Without changing the .rpt file on disk?

I really don't want to have to maintain a separate .rpt file for every financial report that we have in our application.

I'm using Visual Studio Premium 2013 (12..21005.1)
My application is compiled with .NET 4.0

Crystal for VS (13.0.16.1954)

Accepted Solutions (1)

Accepted Solutions (1)

0 Kudos

As long as you don't save the report it's not going to be saved to disk and only gets changed in memory.

Former Member
0 Kudos

Ok, so following the other threads solution. I did something like this:

/* BEGIN CODE */

CrystalDecisions.CrystalReports.Engine.ReportDocument report;

report = new CrystalDecisions.CrystalReports.Engine.ReportDocument();

report.Load(rptFileName);

///// Adding code to modify Numeric Format ///////


ISCDReportClientDocument rptClient = report.ReportClientDocument;

CrystalDecisions.ReportAppServer.ReportDefModel.ReportObjects rptObjs = rptClient.ReportDefController.ReportObjectController.GetReportObjectsByKind(

CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindField);

foreach (CrystalDecisions.ReportAppServer.ReportDefModel.ReportObject rptObj in rptObjs)

{

     if (rptObj != null

&& rptObj.Kind == CrystalDecisions.ReportAppServer.ReportDefModel.CrReportObjectKindEnum.crReportObjectKindField)

     {

     ISCRFieldObject fldObj = (CrystalDecisions.ReportAppServer.ReportDefModel.FieldObject)rptObj;

          if (fldObj.FieldValueType == CrystalDecisions.ReportAppServer.DataDefModel.CrFieldValueTypeEnum.crFieldValueTypeNumberField ||

fldObj.FieldValueType == CrystalDecisions.ReportAppServer.DataDefModel.CrFieldValueTypeEnum.crFieldValueTypeCurrencyField)

          {

               fldObj.FieldFormat.NumericFormat.CurrencySymbolFormat = CrystalDecisions.ReportAppServer.ReportDefModel.CrCurrencySymbolTypeEnum.crCurrencySymbolTypeNoSymbol;

               fldObj.FieldFormat.NumericFormat.DecimalSymbol = ",";

               fldObj.FieldFormat.NumericFormat.ThousandSymbol = ".";

          }

     }

}

/////// Numeric Format changes complete /////////

report.SetDataSource(data);

report.ExportToDisk(ExportFormatType.PortableDocFormat, pdfFileName);

/* END CODE */

It didn't print the new Decimal and Thousand symbols. Is there a step I'm missing?

0 Kudos

Hi Andrew,

To be able to change the symbol you need to clone the object and then change it and then set the viewer to the RAS object.

Download the test app I created in KBA - 2281780 which points to a Doc with the app attached.

Then look for this section, it's in the drop down list, and change the field name and add the line of code to change the Currency symbol.

//// This works do not change

if (fldObj1.Name == "OrderAmount1") // change this to your Reports Object name

{

    CrystalDecisions.ReportAppServer.ReportDefModel.FieldObject OldfieldObject = (CrystalDecisions.ReportAppServer.ReportDefModel.FieldObject)rptObj1;

    CrystalDecisions.ReportAppServer.ReportDefModel.FieldObject NewfieldObject = new CrystalDecisions.ReportAppServer.ReportDefModel.FieldObject();

    //OldfieldObject.CopyTo(NewfieldObject, true);

    NewfieldObject = (CrystalDecisions.ReportAppServer.ReportDefModel.FieldObject)OldfieldObject.Clone(true);

    CrystalDecisions.ReportAppServer.ReportDefModel.NumericFieldFormat numericFieldFormat = NewfieldObject.FieldFormat.NumericFormat;

    //CrystalDecisions.ReportAppServer.ReportDefModel.CrCurrencySymbolTypeEnum = CrCurrencySymbolTypeEnum.crCurrencySymbolTypeFixedSymbol;

// add this line to change the object symbol

    ((dynamic)NewfieldObject).FieldFormat.NumericFormat.CurrencySymbol = "#";

    //numericFieldFormat.NDecimalPlaces = 8;

    //numericFieldFormat.EnableUseLeadZero = false;

    ////numericFieldFormat.ThousandSymbol = "&";

    ////numericFieldFormat.ThousandsSeparator = true;

    //numericFieldFormat.NegativeFormat = CrystalDecisions.ReportAppServer.ReportDefModel.CrNegativeTypeEnum.crNegativeTypeLeadingMinus;

    //numericFieldFormat.RoundingFormat = CrystalDecisions.ReportAppServer.ReportDefModel.CrRoundingTypeEnum.crRoundingTypeRoundToTenBillionth;

    rptClientDoc.ReportDefController.ReportObjectController.Modify(OldfieldObject, NewfieldObject);

    // NOTE: note sure if this is required now - Another bug in the controller need to call this 2 times to take the Rounding property - same as ADAPT01727457

    rptClientDoc.ReportDefController.ReportObjectController.Modify(OldfieldObject, NewfieldObject);

    IsRpt = false;

}

//// This works do not change

Don

Former Member
0 Kudos

I'm trying this now, but just to be sure:

What is the context of this code? Meaning, what type is fldObj1 and rptObj1 and where were they derived from? It seems there are some ambiguous class names in the Report models and I want to make sure I'm following the right path.

Former Member
0 Kudos

I got it to work.

I didn't understand the different between fldObj1 and rptObj1, so I renamed rptObj1 to fldObj1.

Then I changed your control line:

if (fldObj1.Name == "OrderAmount1") // change this to your Reports Object name

{

with this:

ISCDReportClientDocument rptClientDoc = report.ReportClientDocument;

CrystalDecisions.ReportAppServer.ReportDefModel.ReportObjects rptObjs =

rptClientDoc.ReportDefController.ReportObjectController.GetReportObjectsByKind(CrReportObjectKindEnum.crReportObjectKindField);

foreach (ISCRReportObject fldObj1 in rptObjs)

{

if (((ISCRFieldObject)fldObj1).FieldValueType == CrystalDecisions.ReportAppServer.DataDefModel.CrFieldValueTypeEnum.crFieldValueTypeNumberField

|| ((ISCRFieldObject)fldObj1).FieldValueType == CrystalDecisions.ReportAppServer.DataDefModel.CrFieldValueTypeEnum.crFieldValueTypeNumberField)

{

...basically grabbing all numeric and currency fields. It worked for the most part. There were a few fields it left out for some reason, but I'm pretty sure I can figure that out.

Thanks!

0 Kudos

Great, there are multiple ways to get things to work, my sample app is just one way....

Don

ido_millet
Active Contributor
0 Kudos

> There were a few fields it left out for some reason...


Probably because instead of checking for numeric or currency you are checking for numeric or numeric.



Former Member
0 Kudos

I saw that, it fixed the problem.

Thanks!

Answers (0)