Crystal Reportsのラベル(列ヘッダー、フィールドラベル、ヘッダー/フッターなど)をローカライズするには、どのような方法が適していますか?ローカライズされたCrystal Reports
私たちは現在XI R2 SP4を使用していますが、2008に移行しようとしています。2008年のように、ビューアのUIのローカリゼーションが改善されているようです。コンテンツローカリゼーションの話題はありますか?
Crystal Reportsのラベル(列ヘッダー、フィールドラベル、ヘッダー/フッターなど)をローカライズするには、どのような方法が適していますか?ローカライズされたCrystal Reports
私たちは現在XI R2 SP4を使用していますが、2008に移行しようとしています。2008年のように、ビューアのUIのローカリゼーションが改善されているようです。コンテンツローカリゼーションの話題はありますか?
2つのオプションは次のとおりです:1)ローカライズされたバージョンごとに別々のレポートを作成する(これは醜いですが、非常に高くすることはお勧めしません)または2) ac#windows/web app)、次に.netのローカリゼーション標準を使ってローカライズし、ローカライズされたすべてのテキスト(リソースファイルから読み込み)をコード内に設定することができます。
私は2008年についてはわかりませんが、XI R2もあります。各言語のレポートはローカライズされていますが、3つの異なるローカライズ版のみが必要であることがわかっているためです。
クライアントから、ローカリゼーション戦略の策定が依頼されました。私はそれに記事を書くことを意味してきました。あなたのおかげで、私はちょうどそれをやった。 http://www.cogniza.com/blog/?p=55
編集:ローカライゼーション値のデータベースを参照
Iは、(レポートヘッダセクション)埋め込みサブレポートを使用することができました。私はそれを私の投稿に追加したでしょうが、それはかなり複雑でした。
このタスクを処理するユーザー関数ライブラリ(UFL)を作成することもできます。データをデータベースまたはXMLファイルに格納します。ただし、ほとんどの場合、ContentLocale機能が失われます。
リンク腐敗の場合の考え方の要約:Crystal XI ContentLocale変数をチェックしてローカライズされた文字列を返すカスタム関数を作成します。 –
私は、実際の翻訳をカスタム関数自体に入れるという考えが嫌いです。これは、翻訳をアウトソーシングする際に頭痛を引き起こします。 –
Crystal ReportsのDateTimesなどの値のローカライズ方法を発見しました。
たとえば、日付が2009年8月で文化がフランス語の場合、août-2009として表示されます。
このすべては、現在のスレッドカルチャをフランス語に切り替えることなく行います。
関連するコードスニペット(例):
//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());
我々は最終的にレポートのローカリゼーションを実装するに周りました。 Crystal Reportsの読み込みは、既にアプリのユーザーエクスペリエンスの中で最も遅い/最悪の部分であるため、パフォーマンスの影響を避けたいと考えていました。私たちの決定を通知したもう一つのアイデアは、出荷されたリリースで翻訳が変更されないということでした。
私たちは、Crystal Reports API(2008年 - RDCはありません)を使用するアプリケーションを開発し、2つのフェーズで動作します。
最初の段階では、すべてのテキストをスクラップして英語の.resxファイルに出力します。これの最も難しい部分は、関数内で翻訳可能なテキストを特定し、埋め込みフィールドを「翻訳しない」ことを示すトークンに置き換えることです。
resxのローカライズ版が復帰した後、アプリの第2段階で各レポートが各resxと共に取得され、英語が翻訳されたテキストに置き換えられた新しいレポートが保存されます。これにより、日本語のレポートでのみフォントをMSゴシックに切り替えることができ、「ユニバーサル」フォントをライセンスする必要がなくなりました。 「ユニバーサル」フォント(例えば、Arial Unicode MS)の日本語の文字は、やりとりのように見える傾向があります。
Crystal APIはbyzantineであり、関数や埋め込みフィールド内で翻訳可能な文字列を検出する場合には注意が必要です。PageNofMのような組み込みフィールドには注意してください。中括弧で囲まれていません。(これを{field}のPage {field}に置き換えて "page"と "of"を翻訳できるようにする必要はありません。 1つのポインタでコントローラを使用して既存のアイテムをクローン/変更されたコピーに置き換えることができます。あなたがこの道を行くならば幸いですが、結局それが最良の選択だと思っています。
単結晶複数の言語のレポートを使用
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();
'resBundle'とは何ですか? if/elseブロックのコードが同じ理由は何ですか? –
#2は、各テキストフィールドをスキャンし、ローカライズされたテキストを置き換えるためにRDCを使用しているのでしょうか? –
はい、私はそれをやったことはありませんでしたので、どのような頭痛が伴うのかよく分かりません。 –
ローカライズされた文字列を返すUFLについてどう思いますか?各レーベルフィールドからそれをパフォーマンスの問題と呼ぶでしょうか? –