Localized Crystal Reports - crystal-reports

What is a good method to localize labels (column headings, field labels, headers/footers, etc) on Crystal Reports?
We are currently on XI R2 SP4 but are looking to migrate to 2008. It looks like 2008 offers better localization of the viewer UI. Does it have a content localization story?

Found a way to for localization of values such as DateTimes in Crystal Reports.
For instance if date is Aug-2009 and culture is French then would display as août-2009.
All this WITHOUT switching the current Thread culture to French.
Relevant Code snippet (example):
//Locale must be set BEFORE report is opened
if (this.IsEnglish)
{
ReportDoc.ReportClientDocument.PreferredViewingLocaleID =
CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleEnglishCanada;
ReportDoc.ReportClientDocument.LocaleID =
CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleEnglishCanada;
ReportDoc.ReportClientDocument.ProductLocaleID =
CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleEnglishCanada;
}
else
{
ReportDoc.ReportClientDocument.PreferredViewingLocaleID =
CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleFrenchCanada;
ReportDoc.ReportClientDocument.LocaleID =
CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleFrenchCanada;
ReportDoc.ReportClientDocument.ProductLocaleID =
CrystalDecisions.ReportAppServer.DataDefModel.CeLocale.ceLocaleFrenchCanada;
}
//Load the report from file path
ReportDoc.Load(reportPath.ToString());

The two options that I can think of are: 1) Have a separate report for each localized version (this gets ugly quick and I don't recommend it very highly) or 2) Have the report generated from an application (say a c# windows/web app) and then you can localize using .net's localization standards and setting all of the localized text (read in from resource files) in the code.
I am not certain about 2008 but we are also on XI R2. We have localized reports for each language but only because we * know * that we will only need three different localized versions.

A client asked me to do develop a localization strategy for them. I've been meaning to write an article on it. Thanks to you, I've done just that. http://www.cogniza.com/blog/?p=55
Edit:
I was able to use an embedded subreport (in the report-header section) that referenced a database of localization values. I would have added that to my posting, but it was quite complex.
Another option is to create a user-function library (UFL) that handles this tasks. Store the data in a database or XML file. Most likely, however, you will lose the ContentLocale functionality.

We finally got around to implementing report localization. Loading of Crystal Reports is already the laggiest/worst-performing part of the user experience in our app, so we wanted to avoid any performance impact. The other idea that informed our decision was that the translations won't change within a shipped release.
We developed an application that uses the Crystal Reports API (2008 - so there's no RDC) and works in two phases.
First phase is to scrape all of the text and output to an English .resx file. Toughest part of this is identifying translatable text within functions, and replacing embedded fields with tokens indicating "don't translate."
After the localized versions of the resx come back, the second phase of the app takes each report along with each resx and saves out new reports with English replaced with translated text. This also allowed us to switch out the fonts only in Japanese reports to MS Gothic, thereby avoiding the need to license a "universal" font. The Japanese characters in "universal" fonts (e.g. Arial Unicode MS) tend to look like crap.
The Crystal API is byzantine, and you need to be careful with edge cases around detecting translatable strings within functions and embedded fields. Be careful with the builtin fields like PageNofM, they aren't enclosed in curly braces (not to mention that you should replace this with Page {field} of {field} so "page" and "of" can be translated). One pointer, use the controllers to replace existing items with cloned/modified copies, you can't just modify the text content of items in place. Good luck if you go this route, but in the end we think it's the best option.

Single Crystal report Use for multiple language
if (CultureInfo.CurrentCulture.Name == "en-US")
{
(obj.ReportDefinition.ReportObjects["lbleverest"] as TextObject).Text = resBundle.GetString("Localization", "everest");
(obj.ReportDefinition.ReportObjects["lblmandlicode"] as TextObject).Text = resBundle.GetString("Localization", "SocietyCode");
(obj.ReportDefinition.ReportObjects["MandliName1"] as FieldObject).ApplyFont(new Font(resBundle.GetString("Localization", "Font"), Convert.ToInt32(resBundle.GetString("Localization", "FontSize")), FontStyle.Regular));
(obj.ReportDefinition.ReportObjects["shortName1"] as FieldObject).ApplyFont(new Font(resBundle.GetString("Localization", "Font"), Convert.ToInt32(resBundle.GetString("Localization", "FontSize")), FontStyle.Regular));
}
else
{
(obj.ReportDefinition.ReportObjects["lbleverest"] as TextObject).Text = resBundle.GetString("Localization", "everest");
(obj.ReportDefinition.ReportObjects["lblmandlicode"] as TextObject).Text = resBundle.GetString("Localization", "SocietyCode");
(obj.ReportDefinition.ReportObjects["MandliName1"] as FieldObject).ApplyFont(new Font(resBundle.GetString("Localization", "Font"), Convert.ToInt32(resBundle.GetString("Localization", "FontSize")), FontStyle.Regular));
(obj.ReportDefinition.ReportObjects["shortName1"] as FieldObject).ApplyFont(new Font(resBundle.GetString("Localization", "Font"), Convert.ToInt32(resBundle.GetString("Localization", "FontSize")), FontStyle.Regular));
}
obj.DataDefinition.FormulaFields["lang"].Text = "'" + CultureInfo.CurrentCulture.Name + "'";
cv.crystalReportViewer1.ReportSource = obj;
cv.Show();

Related

Numbering is missing on body.getOoxml() in Word 2016 MSO

Using body.getOoxml() in an add-in for Word 2016 does not include the numbering package part. This leads to errors when executing insertooxml() since the API creates new numbering definitions which are wrong or default to the standard (as 1,2,3 etc.). Hence numberings that have other logic, like lower letters or roman letters, will be set back to the standard on executing insertooxml().
This applies to Word 2016 MSO which still uses IE 11 in add-ins. (nothing we can do about that).
In Word for M365 it works correctly.
The Word version in use is 16.0.5369.1000 MSO 16.0.5366.1000 32-Bit (Running on Windows 10)
We currently use Office-js version 1.1.82 (the newest 1.1.83-custom.0 has a bug that throws an exception on insertooxml in Word 2016)
We need this for our solution which removes sensitive data from word documents. Since Word Js Api 1.1 does not include hyperlinks, we need to operate on ooxml to fix hyperlinks as well.
Steps to recreate:
Create a new word document
Add one or two titles
Change title numbering to "a,b,c"
Execute the following code in an add-in:
var body = context.document.body;
var body_ooxml = body.getOoxml();
await context.sync();
var body_ooxml_value = body_ooxml.value;
body.insertOoxml(body_ooxml_value, Word.InsertLocation.replace);
await context.sync();
What I expected:
The content of the document should remain the same. Without any changes to the numbering
current findings
I made several tests and found out that in Word 2016 MSO, getOOXML does not return the numbering - even though the file numbering.xml exists and is correct. After executing insertOoxml it seems as if the api is trying to re-create the numbering from scratch which leads to an overwrite in numbering.xml that includes standard numbering (1,2,3).
I don't see a workaround (but would be happy for any advice).This seems to be a product bug and needs to fixed.
Just FYI, in case you didn't know: Microsoft no longer requires support for IE in add-ins that are distributed through AppSource. That said, it does seem to be a bug, so you could create a bug issue on the office-js repo. But I don't think a bug in an Office version that old will have a high priority.

How to retrieve crystal report page(section) name using c#

I have crystal report that I want to separate by the page(section) name and create a pdf file. I've been looking everywhere and have not found and answer. Hopefully someone can help.
`
foreach (ReportDocument pgnName in rpt)
{
exportOpts.ExportFormatOptions = pdfRtfWordOpts;
exportOpts.ExportFormatType = ExportFormatType.PortableDocFormat;
destinationOpts.DiskFileName = "C:\\Temp\\report File" + pgnName+ ".pdf";
exportOpts.ExportDestinationOptions = destinationOpts;
exportOpts.ExportDestinationType = ExportDestinationType.DiskFile;
rpt.Export(exportOpts);
}
Couldn't find anything.
The Crystal runtime doesn't provide such an option.
Building report bursting functionality (by page or by group logic) is fairly complex. Your question seems to suggest you are not very familiar with the Crystal Reports object model. So consider 3rd-party Crystal Reports automation tools. Ken Hamady maintains a listing of such tools here. And several of them support report bursting.
Some of these tools also provide an option to export the report to PDF and burst the PDF by page, by bookmark, or by hidden tag formula. That approach may be easier for you to implement in your own code.

Creating a translator/dictionary in IOS

So Im importing a text file that contains a list of character sets. These sets have a meaning they refer to a status of an object. For example TOMTOM100 means Delivery announced. Ones i import he text file the status is presented in 0-5 labels(depends on how many status updates are available).
At first i wanted to do this with a if statement but quickly realized that it would be to much.
if ((trackTraceStatusone.text = #"TOMTOM100"))
{
trackTraceStatusone.text = #"Delivery announced.";
}
Is there a way to create some kind of translator that automatically translates the status in a readable format?
TOMTOM100 > Delivery announced
TOMTOM101 > Delivery Scanned
and so on.
Sounds like a job for NSLocalizedStringFromTable() or the corresponding NSBundle method -localizedStringForKey:value:table:. This will let you load the string from a .strings file in your bundle, which will look something like this:
"TOMTOM100" = "Delivery Announced";
"TOMTOM101" = "Delivery Scanned";
This will also make it easy to provide different strings for different languages. For more information, see the String Resources section of the Resource Programming Guide.

How do you put a version number into an rdlc file?

I've a couple of rdlc files which I change everytime business has additional requirements. The problem is that we keep pdfs of the reports we create, and it's impossible right now to see what version of the rdlc file it was created with.
I've thought about putting a text field with "Version XX.Y" into the footer, but then I have to remember to update this when I make changes. It's not the worst solution in the world, but I'd like to hear how others handle report versioning in reporting services.
Note that I am renedering reports using local reporting, i.e. no server, so I've thought about somehow trying to display the assembly version of the application running the report. This I can control more easily with .* notation in assemblies, but I'm not sure how to have a text field which would show this.
You could add a property containing the assembly version to the report's data source (or pass the value in some other way).
public string AssemblyVersion {
get {
return Assembly.GetAssembly(typeof(WhateverTypeThisIs)).GetName().Version;
}
}
Another option might be to use an MSBuild task to replace the version number in the .rdlc for you. XMLPoke, for instance.
If you are using subversion, an option might be to use the SvnInfo task from MSBuild community tasks to get the last changed rev of the report and use that number to update the XML of the rdlc file.

Crystal Report .NET font changing

I've designed a crystal report that will be sent to a specific (barcode) printer through a web interface. Allowing the report to be generated in the standard crystal report viewer was causing issues, so I am now using the code-behind to send the report directly to the printer.
ReportDocument Report = new ReportDocument();
ParameterDiscreteValue Order = new ParameterDiscreteValue();
Order.Value = Convert.ToInt32(txtOrder);
Report.Load(reportPath);
Report.SetParameterValue("OrderNo", Order);
PageMargins margins;
margins = Report.PrintOptions.PageMargins;
margins.bottomMargin = 0;
margins.leftMargin = 0;
margins.rightMargin = 0;
margins.topMargin = 0;
Report.PrintOptions.ApplyPageMargins(margins);
Report.PrintOptions.PrinterName = "\\\\printserver\\Zebra Z6M Plus (300dpi)";
Report.PrintToPrinter(1, false, PageNum, PageNum);
Report.Close();
When printed from the designer (CRXI) everything works fine but when the web interface sends the job to a printer (any printer) it changes the font to Times New Roman which messes up all of the field sizes. If I use the standard .NET report viewer it uses the correct font, so I'm pretty sure the change is being caused by creating/using the ReportDocument.
How can I send the report directly to a print without it defaulting the fonts back to Times New Roman?
This idea occured to me:
Instead of sending the report straight from Crystal to the printer, what if you use some kind of middleman, i.e. export the .rpt to .pdf first, then print the PDF?
(Yes, it would be a very "wooden tables" tables approach, but if it works, it works.)
While it seemed like the special font I was using had been included on every server imaginable, I was never able to get it to work through the web interface.
I ended up finding a standard windows font that mostly suited the needs of this project and have given up on trying to beat this problem.
You need use RAS SDK API. Crystal Reports for Visual Studio 2010 (v13) include this api. (This code don't work in Crystal Reports for Visual Studio 2005... I don't have info about other versions)
Add this references to your existing code:
CrystalDecisions.ReportAppServer.ClientDoc
CrystalDecisions.ReportAppServer.Controllers
CrystalDecisions.ReportAppServer.ReportDefModel
And use this code (VB... sorry)
Using rpt As New CrystalDecisions.CrystalReports.Engine.ReportDocument
rpt.Load(file, CrystalDecisions.[Shared].OpenReportMethod.OpenReportByTempCopy)
rpt.SetDataSource(_ReportSource)
Dim options As New CrystalDecisions.ReportAppServer.Controllers.PrintReportOptions
options.Collated = _Collate
options.NumberOfCopies = _Copies
' TODO: Implement_startPageN and _endPageN
Dim optPrint As CrystalDecisions.ReportAppServer.ReportDefModel.PrintOptions
optPrint = rpt.ReportClientDocument.PrintOutputController.GetPrintOptions
optPrint.PrinterName = _PrinterName rpt.ReportClientDocument.PrintOutputController.ModifyPrintOptions(optPrint)
rpt.ReportClientDocument.PrintOutputController.PrintReport(options)
rpt.Close()
End Using
I was trying to change Crystal Report Font according to data that will be shown on the report.
I use Formate Formula to change the font using flags Condition.
if({?vIsRightToLeft}=true)then
"Attari Font"
Else
"Arial"