2009-05-20 10 views
5

Quelle est une bonne méthode pour localiser des étiquettes (titres de colonne, étiquettes de champ, en-têtes/pieds de page, etc.) sur Crystal Reports?Crystal Reports localisés

Nous sommes actuellement sur XI R2 SP4 mais nous cherchons à migrer vers 2008. Il semble que 2008 offre une meilleure localisation de l'interface utilisateur. A-t-il une histoire de localisation de contenu?

Répondre

2

Les deux options que je peux penser sont: 1) Avoir un rapport séparé pour chaque version localisée (cela devient très rapide et je ne le recommande pas très fortement) ou 2) Avoir le rapport généré à partir d'une application (disons aC# windows/application web) et ensuite vous pouvez localiser en utilisant les normes de localisation de .net et en définissant tout le texte localisé (lu à partir des fichiers de ressources) dans le code. Je ne suis pas certain à propos de 2008, mais nous sommes également sur XI R2. Nous avons localisé des rapports pour chaque langue, mais seulement parce que nous * savons * que nous n'aurons besoin que de trois versions localisées différentes.

+0

# 2 serait en utilisant la RDC pour parcourir chaque champ de texte et le remplacer par le texte localisé? –

+0

Oui - je ne l'ai jamais fait cependant je ne sais pas quel genre de maux de tête sont impliqués. –

+0

Que pensez-vous d'une UFL renvoyant des chaînes localisées? Est-ce que l'appel à partir de chaque champ d'étiquette serait un problème de performance? –

0

Un client m'a demandé de développer une stratégie de localisation pour lui. J'ai eu l'intention d'écrire un article là-dessus. Grâce à vous, je l'ai fait. http://www.cogniza.com/blog/?p=55

Edit:

J'ai pu utiliser une base de données qui fait référence à une des valeurs de localisation sous-état intégré (dans la section d'en-tête du rapport). J'aurais ajouté cela à mon article, mais c'était assez complexe.

Une autre option consiste à créer une bibliothèque de fonctions utilisateur (UFL) qui gère ces tâches. Stockez les données dans une base de données ou un fichier XML. Cependant, il est fort probable que vous perdiez la fonctionnalité ContentLocale.

+0

Résumant l'idée en cas de lien rot: créez une fonction personnalisée qui renvoie une chaîne localisée en vérifiant la variable Crystal XI ContentLocale. –

+2

Je n'aime pas l'idée de placer les traductions réelles dans la fonction personnalisée elle-même. Cela créera des maux de tête lors de l'externalisation des traductions. –

2

Nous avons trouvé un moyen de localiser des valeurs telles que DateTimes dans Crystal Reports.
Par exemple si la date est août-2009 et que la culture est française, alors affichera août-2009.
Tout cela SANS changer la culture actuelle du fil en français.

extrait de code approprié (exemple):

  //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()); 
1

Nous avons finalement eu le temps de mettre en œuvre la localisation du rapport. Le chargement de Crystal Reports est déjà la partie la plus retardée/la moins performante de l'expérience utilisateur dans notre application, nous voulions donc éviter tout impact sur les performances. L'autre idée qui a motivé notre décision était que les traductions ne changeraient pas dans une version embarquée.

Nous avons développé une application qui utilise l'API Crystal Reports (2008 - il n'y a donc pas de RDC) et fonctionne en deux phases.

La première phase consiste à récurer tout le texte et à générer un fichier anglais .resx. La partie la plus difficile consiste à identifier le texte traduisible dans les fonctions et à remplacer les champs incorporés par des jetons indiquant «ne pas traduire». Après que les versions localisées de la resx reviennent, la deuxième phase de l'application prend chaque rapport avec chaque resx et enregistre de nouveaux rapports avec l'anglais remplacé par du texte traduit. Cela nous a également permis de désactiver les polices uniquement dans les rapports japonais vers MS Gothic, évitant ainsi d'avoir à utiliser une police "universelle". Les caractères japonais dans les polices "universelles" (par exemple Arial Unicode MS) ont tendance à ressembler à de la merde. L'API Crystal est byzantine, et vous devez faire attention aux cas de détection de chaînes traduisibles dans les fonctions et les champs incorporés.Soyez prudent avec les champs intégrés comme PageNofM, ils ne sont pas entourés d'accolades (pour ne pas mentionner que vous devez remplacer cela par Page {field} de {field}, donc "page" et "of" peuvent être traduits). Un pointeur, utilisez les contrôleurs pour remplacer les éléments existants avec des copies clonées/modifiées, vous ne pouvez pas simplement modifier le contenu du texte des éléments en place. Bonne chance si vous suivez cette route, mais à la fin, nous pensons que c'est la meilleure option.

-1

rapport Crystal à usage unique pour plusieurs langues

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(); 
+0

Qu'est-ce que 'resBundle'? Pourquoi le code dans les blocs if/else est-il le même? –