2009-05-20 27 views
5

Qual è un buon metodo per localizzare le etichette (intestazioni di colonna, etichette di campo, intestazioni/piè di pagina, ecc.) Su Crystal Reports?Crystal Reports localizzati

Attualmente siamo su XI R2 SP4 ma stiamo cercando di migrare al 2008. Sembra che il 2008 offra una migliore localizzazione dell'interfaccia utente del visualizzatore. Ha una storia di localizzazione dei contenuti?

risposta

2

Le due opzioni che posso pensare sono: 1) Avere un rapporto separato per ogni versione localizzata (questo diventa brutto rapidamente e io non lo consiglio molto) o 2) Avere il report generato da un'applicazione (ad esempio aC# windows/web app) e quindi è possibile localizzare utilizzando gli standard di localizzazione di .net e impostare tutto il testo localizzato (letto dai file di risorse) nel codice.

Non sono sicuro del 2008 ma siamo anche su XI R2. Abbiamo rapporti localizzati per ogni lingua, ma solo perché * sappiamo * che avremo bisogno solo di tre diverse versioni localizzate.

+0

# 2 sarebbe utilizzando il desktop remoto per eseguire la scansione attraverso ogni campo di testo e sostituirlo con il testo localizzato? –

+0

Sì, non l'ho mai fatto, quindi non sono sicuro di quale tipo di mal di testa siano coinvolti. –

+0

Cosa ne pensi di un UFL che restituisce stringhe localizzate? Chiamare questo da ogni campo etichetta sarebbe un problema di prestazioni? –

0

Un cliente mi ha chiesto di sviluppare una strategia di localizzazione per loro. Ho intenzione di scrivere un articolo su di esso. Grazie a te, ho fatto proprio questo. http://www.cogniza.com/blog/?p=55

Edit:

ero in grado di utilizzare un sottoreport incorporato (nella sezione di report-header), che fa riferimento un database di valori di localizzazione. L'avrei aggiunto al mio post, ma era piuttosto complesso.

Un'altra opzione è creare una libreria di funzioni utente (UFL) che gestisca queste attività. Memorizza i dati in un database o file XML. Molto probabilmente, tuttavia, perderai la funzionalità di ContentLocale.

+0

Riepilogando l'idea in caso di interruzione di collegamento: creare una funzione personalizzata che restituisca una stringa localizzata controllando la variabile ContentLocale di Crystal XI. –

+2

Non mi piace l'idea di inserire le traduzioni effettive nella funzione personalizzata stessa. Ciò creerà mal di testa quando si esternalizzano le traduzioni. –

2

Trovato un modo per la localizzazione di valori come DateTimes in Crystal Reports.
Ad esempio se la data è agosto-2009 e la cultura è francese, verrà visualizzata come août-2009.
Tutto questo senza passare alla cultura del filo corrente in francese.

Rilevante frammento di codice (esempio):

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

Abbiamo finalmente ottenuto intorno ad attuare rapporto localizzazione. Il caricamento di Crystal Reports è già la parte più lenta/peggiore dell'esperienza utente nella nostra app, quindi abbiamo voluto evitare qualsiasi impatto sulle prestazioni. L'altra idea che ha informato la nostra decisione è stata che le traduzioni non cambieranno all'interno di una versione spedita.

Abbiamo sviluppato un'applicazione che utilizza l'API di Crystal Reports (2008 - quindi non c'è RDC) e funziona in due fasi.

La prima fase consiste nel raschiare tutto il testo e l'output in un file .resx in inglese. La maggior parte di questo è l'identificazione del testo traducibile all'interno delle funzioni e la sostituzione di campi incorporati con token che indicano "non tradurre".

Dopo che le versioni localizzate del resx sono tornate, la seconda fase dell'app prende ciascun rapporto insieme a ciascuna resx e salva nuovi report con l'inglese sostituito con il testo tradotto. Questo ci ha anche permesso di spostare i font solo nei report giapponesi su MS Gothic, evitando così la necessità di ottenere la licenza di un font "universale". I caratteri giapponesi nei caratteri "universali" (ad esempio Arial Unicode MS) tendono a sembrare schifosi.

L'API Crystal è bizantina e occorre prestare attenzione ai casi limite relativi al rilevamento di stringhe traducibili all'interno di funzioni e campi incorporati.Fai attenzione ai campi predefiniti come PageNofM, non sono racchiusi tra parentesi graffe (per non parlare del fatto che dovresti sostituirlo con Pagina {campo} di {campo} così "pagina" e "di" possono essere tradotti). Un puntatore, usa i controller per sostituire gli oggetti esistenti con copie clonate/modificate, non puoi semplicemente modificare il contenuto del testo degli oggetti in posizione. Buona fortuna se segui questa strada, ma alla fine pensiamo che sia l'opzione migliore.

-1

report Crystal uso singolo per più lingue

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

Che cos'è 'resBundle'? Perché il codice nel se/else blocca lo stesso? –

Problemi correlati