For companies with many international reports, using a database is the ideal solution. Unfortunately, this has its own set of problems to contend with. You can’t use the ContentLocale formula in the record selection formula. It can only be evaluated in the second report pass after all the records have been read into the report. So you can’t filter the data in the Language table based on regional settings. This creates quite a problem. There are various ways to handle this but none of them are perfect. You have to figure out which one you are comfortable implementing and which works best for your situation. Some possible solutions are as follows:
- Specify the language within the record selection formula. For example, you could use this record selection formula: {Language.ConentLocaleID}=”en”. Unfortunately, this means that each report can only be used for one language. You still get the benefit of sharing the database among multiple reports, but you need a separate copy of the report for each language and must modify the record selection formula accordingly.
- A trick I discuss in the chapter on parameters is to use the report as a subreport within a blank main report. The blank main report only has one formula which returns the ContentLocale function. Link this formula to a parameter in the subreport so that it can be used in the record selection formula. By having the main report pass the ContentLocale function to the subreport, the regional setting is available to the subreport when the records are being read from the database. This is a semi-acceptable solution except that treating the report as a subreport is a bit unusual and having to do it for many reports can be a hassle. Caution: since Crystal Reports doesn’t let you nest subreports more than one level deep, this solution only works if the report doesn’t have subreports.
- Depending upon your database, it could be possible to get around using the ContentLocale function by associating each report with a regional setting. One way to do this is to find a unique identifier in the report that can be used to differentiate where the report is being printed. For example, if the report header uses an address table to print the office’s location, you can use that to determine which country the report is being printed from. You can add a locale field to the table that holds the office location. By linking the Language table to the corporate office table and joining on the locality field, each report can print in the correct language with modifying the record selection formula or calling the ContentLocale function.
- If you’re building a reporting solution using Visual Studio .NET or Java, you can use a parameter within the record selection formula to set the locality. You set the parameter within your application prior to displaying the report. This is the best solution, but it only works if you know how to use one of these programming languages.
To test whether your report works with each of the possible regional settings, you can change the region through the Control Panel. However, Crystal Reports doesn’t immediately recognize when a change is made. It continues to use the original setting. Crystal Reports only checks the regional settings one time and stores it internally for the duration of your login. Even closing and re-opening Crystal Reports doesn’t update it. You need to log off and log back on to the computer to force Crystal Reports to recognize the new regional setting.
When printing date and time information in other countries, sometimes it is helpful to determine the local time zone of where the report is being printed and shift the time according to the regional settings. Crystal Reports gives you three date and time functions that reference regional settings. They are listed in Table 15-3.
Table 15-3. Region specific data and time functions.
Function | Description |
---|---|
DataTimeZone | The time zone of the DataTime special field (when the report’s data was last refreshed). |
PrintTimeZone | The time zone of the PrintTime special field (when the report was printed). |
ShiftDateTime(DateTime, OldTimeZone, NewTimeZone ) | Shifts the date and time zone to appear in a new time zone. You have to pass it the date and time to shift as well as the current and new time zones. |