読者です 読者をやめる 読者になる 読者になる

CrystalReportsの印字位置をC#側で直接指定する

はじめまして。ゴルフ場基幹システム開発リラックマ担当のむとうです。
ほぼ生粋の茨城出身です。業務では主にC#SQLServerを触っております。どうぞ宜しくお願いします。


今回のテーマ

弊社の基幹システムでは帳票出力にCrystalReportsを使用しています。
一般的に、レポート内フィールドの「表示/非表示」「フォント指定」などの書式設定を条件によって変える場合、「式エディタ」で制御すると思います。 しかし「フィールドの印字位置」を条件によって変えようとした場合、どのように制御すれば良いのでしょうか。

例えば、

  • 印字位置指定が想定される全ての場所に同じフィールドを配備、非表示制御で制御…

この方法は印字指定が数パターンで済めば力技でできなくもないのですが、ミリ単位でパターンを指定しようなどと考えた日には気が遠くなります。

…と、このような事を悩んだ経緯から、今回は「印字位置を出力元(C#)で直接指定する」方法を書きたいと思います。

環境

.NET Framework 4
C#
Crystal Reports for Visual Studio 2010

下準備

  • 「レポート出力を行う親フォーム」と「プレビュー表示を行う子フォーム」を作成。
  • ハガキ印刷を想定したレポートテンプレートを作成。 f:id:muto70:20151124164504j:plain
    • サンプルなので今回はテキストオブジェクトの直貼りです。
    • 各フィールドは上から[郵便番号][住所1][住所2][氏名]の4つとなります。

動作確認

まずはこのままプレビューを行います。テンプレートのままですね。 f:id:muto70:20151121182113j:plain

実際に印字位置を指定する

親フォーム側にコードを書き足します。

  • フィールド名を指定して位置を動かしてみます。
using (ReportDocument report = new ReportDocument())
    {
        //レポートテンプレート読込
        string path = "C:\\tryProject\\try.rpt";
        report.Load(path);

        // 氏名フィールドを2センチ程右下へ移動
        report.ReportDefinition.ReportObjects["氏名"].Top += 1200;
        report.ReportDefinition.ReportObjects["氏名"].Left += 1200;

        //(以下レポートプレビュー処理)

プレビュー画面。氏名欄のみ右下に移動しました。 f:id:muto70:20151121183846j:plain

  • 全フィールドを纏めて指定して位置を動かしてみます。
using (ReportDocument report = new ReportDocument())
    {
        //レポートテンプレート
        string path = "C:\\tryProject\\try.rpt";
        report.Load(path);

        // 全フィールドを2センチ程右下へ移動
        foreach (ReportObject r in report.ReportDefinition.ReportObjects)
        {
            r.Top += 1200;
            r.Left += 1200;
        }

        //(以下レポートプレビュー処理)

プレビュー画面。全体が右下に移動しました。 f:id:muto70:20151121183847j:plain

良い具合です!


まとめ

今回のサンプルでは「ハガキ用紙枠への印字被り対応」を想定しています。 例えばプリンタの買替などで環境が変わると印字位置も微妙に変わってしまうケースがあるのですが、出力元で印字位置を指定できるようになればエンドユーザー側で印字位置調整が行う事も不可能ではないのです。 今回はプログラム上で印字位置を直接設定していますが、UI側での値指定や外部設定ファイル参照を行えるようにすることで、より柔軟に対応できるようになります。