チュートリアル2 売上明細表

このページではRapidReportの機能を活かした、やや高度な制御を含んだ帳票を作成します。 もしも「チュートリアル1」を終えていないのであれば、 そちらを先に読むことをお勧めします。

作成する帳票の完成イメージは以下のようになります(全2ページとなる例を示します)。

売上げ明細表の1ページ目 売上げ明細表の2ページ目
サンプルについて
完成したサンプルが example フォルダ内に以下の名前で含まれています。 帳票定義ファイル: example2.rrpt ソースコード: Example2.cs、Example2.vb、Example2.java

帳票に渡すデータ

今回の例では、以下のデータを帳票に渡します。

サンプルデータ

この帳票に渡すデータは、部門コード(bumonCd)、伝票番号(denpyoNo)の順でソートされている必要があります。 部門コードが変わると改ページされ、その中で伝票番号ごとに集計が行われます。

集計は伝票ごと、部門ごと行われますが、 どちらの場合も集計対象が1件しかなければ集計行を非表示とします。 つまり、明細が1件しかなければ伝票計は非表示となり、 伝票が1件しかなければ部門計は非表示となるようにします。

レポートデザイナの起動

帳票定義ファイルを作成するために、スタートメニューからレポートデザイナを起動します。

スタートメニューに登録された[レポートデザイナ(.net3.5)]または[レポートデザイナ(.net4.0)]をクリックしてください。 どちらを選ぶかで、レポートデザイナが利用する.NET Frameworkのバージョンが変わります。

※どちらを利用しても機能に違いはありません。ご利用の環境で実行可能なほうを選択して下さい。

※レポートデザイナの使い方についての詳しい説明は、「レポートデザイナ」にあります。

学習ツアーについて
RapidReportのレポートデザイナには、学習ツアーという機能があります。 これは、帳票定義ファイルを作成した際の履歴を全て保存しておき、いつでも再生可能とするものです。 本チュートリアルの帳票を作成した際の履歴を記録した学習ツアーが example\tour\example2.rrtr にあります。 レポートデザイナのメニューで、[学習]>[ツアーを開く]から、学習ツアーファイルexample2.rrtrを開くと、ツアーを開始できます。 学習ツアーファイルを開いて「やり直し」ボタンをクリックしていくと、 サンプル帳票の開発手順を1ステップずつ再生できます。

帳票全体に関わる設定

構成ツリー上で(レポート)を選択し、プロパティの[見出し]を"売上明細表"とします。

用紙を横向きとするために、[用紙設定]の下にある[横方向]にチェックを入れます。

デフォルトのフォントサイズを指定するために、 [フォント]の[+設定]をクリックし、その下にある[フォントサイズ]を13とします。

[カスタム列]の[+設定]をクリックし、[列名]を"kingaku"、[式]を"(* .tanka .suryo)"と設定します。 これで、数量(suryo)と単価(tanka)を掛け合わせた金額(kingaku)というカスタム列が定義されます。

部門グループの定義

構成ツリーの(グループ)を選択して[見出し]を"部門グループ"とします。 このグループは部門コードが変わるたびに分割されるように、[ブレーク条件キー]に"bumonCd"と指定します。

さらに、[改ページ]にチェックを入れます。 これにより、グループが開始されるたびに(つまり、部門コードが変わるたびに)改ページされるようになります。

ヘッダーの定義

構成ツリーで(コンテント)を選択して[見出し]を"ヘッダー"とします。 また、高さを設定するために、[サイズ] > [初期]に110と入力します。 さらに、内容が1ページに収まらなかった場合でも全てのページにヘッダーが表示されるように、[毎ページ表示]のチェックを入れます。

以下のように要素を配置します。

ここで、会社名、集計期間、印刷日付は先ほど示した帳票に渡すデータには含まれていません。 これらのデータは表形式で渡す必要はなく、GlobalScopeという別の手段で帳票に渡します。

GlobalScopeは帳票全体から利用可能なハッシュテーブルで、 プログラムから値を登録しておくと、"global.[キー]"という式で値を得ることができます。 (値を登録する方法は、後ほどプログラムを作成する際に説明します)

今回の例では以下のサンプルデータを用います。

会社名、集計期間(開始)、集計期間(終了)、印刷日時の[フィールド]要素に設定する式はそれぞれ、 "global.kaisha"、"global.startDate"、"global.endDate"、"global.printDate"となります。

"PAGE"という見出しの付いた、ページ数を表示する項目については、 [現在のページ数]/[全体のページ数]という形式で表示を行います。

現在のページ数は"page_count"、全体のページ数は"page_count.total"という式で得ることができますが、 これらの値を組み合わせて1つの項目に表示するには、[テキスト]要素を配置して式埋め込み機能を利用すると便利です。

ページ数を表示する要素の[テキスト]プロパティには、以下のように設定します。

#{}で囲まれた部分は式として評価され、その結果が[テキスト]に埋め込まれます。

プレビュー

ここまでの作業内容を確認するために、 [プレビュー]ボタンから、プレビューウィンドウを開きます。

今回の例のためのテストデータがあらかじめ用意されています。 プレビューウィンドウのメニューで[データ] > [データを開く]から、 インストールフォルダ以下のexample\cs\example\report\example2.rrdtを開きます。

データを編集すると、即座にプレビューに反映されるので、自由に書き換えて試してみてください。 例えば、部門コードを書き換えると、改ページの場所が変わることを確認できるはずです。

ボディの定義

構成ツリーで部門グループを選択し、[右クリック] > [コンテントを追加]をクリックします。 追加されたコンテントの[見出し]を"ボディ"とし、 デザインウィンドウで□をドラッグするか、またはプロパティに直接入力することで、 高さを445とします。

ボディ内に、以下のように要素を配置します。

明細の定義

構成ツリーでボディを選択し、[右クリック] > [グループを追加]をクリックします。 追加されたグループの[見出し]を"明細グループ"とし、 明細がデータ1行ごとに出力されるようにするため、[明細]にチェックを入れます。

続いて、明細グループの下にあるコンテントを選択し、[見出し]を"明細"とします。 さらに、高さを設定するために、プロパティの[サイズ] > [初期]に15と入力します。

明細内に、以下のように要素を配置します。

売上日付の[フィールド]要素に設定する式は".uriageDate"、伝票番号は".denpyoNo"、 商品コードは".shohinCd"、商品名称は".shohin"、 単価は".tanka"、数量は".suryo"、金額は".kingaku"となります。

伝票計の定義

ここまでの作業で、与えられたデータが部門コードごとに分割された上で、 一覧表として表示することができるようになりました。

そこで、次は伝票番号ごとの集計が行われるようにします。

構成ツリーでボディを選択し、[右クリック] > [グループを挿入]をクリックします。 この操作によって、ボディと明細グループとの間に新しいグループとコンテントが追加挿入されます。 追加されたグループの[見出し]を"伝票グループ"とし、[ブレーク条件キー]を"denpyoNo"と指定します。 さらに、その下のコンテントの[見出し]を"伝票ボディ"としておきます。

伝票グループを選択し、[右クリック] > [コンテントを追加]をクリックします。 追加されたコンテントの[見出し]を"伝票フッター1"とします。 さらに、高さを設定するために、[サイズ] > [初期]に15と入力します。

また、ここでは「含まれる明細が1件しかなければ表示しない」という制御を行うために、 [表示条件]に"(> count 1)"と指定します。

伝票フッター1内に、以下のように要素を配置します。 伝票計を得る式は"sum.kingaku"となります。

続いて、伝票の区切り線を表示するためのコンテントを追加します。

再び伝票グループを選択し、[右クリック] > [コンテントを追加]をクリックします。 追加されたコンテントの[見出し]を"伝票フッター2"とします。 さらに、高さを設定するために、[サイズ] > [初期]に5と入力します。

区切り線は常に表示したいので、こちらの表示条件には何も指定しません。

伝票フッター2内に[直線]要素を配置します。

データ件数によっては、伝票計の直前や区切り線の直前で改ページされてしまう場合があります。 これを防ぐために、伝票ボディと伝票フッター1の[改ページ禁止]にチェックを入れておきます。

最後に、さきほど明細内に配置した売上日付と伝票番号に対して、 それぞれの[表示条件]を"state.first"と設定します。 これで、同じ伝票の中では最初の明細にのみ売上日付と伝票番号が表示されるようになります。

プレビューを開いて、ここまでの作業内容を確認してみてください。

部門計の定義

最後に、部門計を追加します。

構成ツリーでボディを選択し、[右クリック] > [グループを挿入]をクリックします。 追加されたコンテントの[見出し]を"部門ボディ"とします。

部門ボディと同じレベルにコンテントを追加して[見出し]を"部門フッター"とします。 さらに、高さを設定するために、プロパティの[サイズ] > [初期]に15と入力します。

部門フッターはその部門内に複数の伝票が含まれていた場合のみ表示されるように、 [表示条件]に"(> count# 1)"と指定します。 単にcountと書いた場合、部門に含まれる明細の数が返されますが、今回得たいのは伝票の数です。 そこで、countの後に#を付けることによって、直下の伝票グループの数が返されるようになります。

部門フッター内に、以下のように要素を配置します。 部門計を得る式は"sum.kingaku"となります。

再びプレビューで確認をしてみてください。

これで、レポートデザイナでの作業は終わりになります。[保存]ボタンから帳票定義ファイルを"example2.rrpt"という名前で保存します。

プログラムの作成

先ほど作成した帳票定義ファイルを用いて、実際に帳票を出力するプログラムを作成します。

言語はC#/VisualBasic/Javaのいずれかを用います。 先ほどの帳票定義ファイルは、プログラムの実行パスの場所に"report\example2.rrpt"という名前で配置されているものとします。

※ここではコード例を示すのみとし、内容の詳しい説明は行いません。帳票出力処理の詳細ついては「帳票出力の仕組み」をご覧ください。
※各言語、各出力形式ごとのサンプルコードが「最小限のコード」にまとまっています。こちらも併せてご確認ください。

C#

参照設定

C#でプログラムを作成する前に、いくつかのdllファイルを参照設定に追加する必要があります。 「プログラム開発の準備」に、どのdllを参照すべきかの説明があります。

データの定義

帳票に渡すデータは、DataTableオブジェクトの形式で用意します。 以下に示すように、データの格納されたDataTableを返すメソッドを用意します。

  private static DataTable getDataTable()
  {
      DataTable ret = new DataTable();
      ret.Columns.Add("bumonCd", typeof(Decimal));
      ret.Columns.Add("bumon", typeof(String));
      ret.Columns.Add("uriageDate", typeof(DateTime));
      ret.Columns.Add("denpyoNo", typeof(Decimal));
      ret.Columns.Add("shohinCd", typeof(String));
      ret.Columns.Add("shohin", typeof(String));
      ret.Columns.Add("tanka", typeof(Decimal));
      ret.Columns.Add("suryo", typeof(Decimal));
      ret.Rows.Add(1, "第一営業部",
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", null),
          1246, "PC00001", "ノートパソコン", 70000, 10);
      ret.Rows.Add(1, "第一営業部",
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", null), 
          1246, "DP00002", "モニター", 25000, 10);
      ret.Rows.Add(1, "第一営業部",
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", null),
          1246, "PR00003", "プリンタ", 20000, 2);
      ret.Rows.Add(1, "第一営業部",
          DateTime.ParseExact("2013/02/10", "yyyy/MM/dd", null),
          1248, "PR00003", "プリンタ", 20000, 3);
      ret.Rows.Add(2, "第二営業部",
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", null),
          1247, "PC00001", "ノートパソコン", 70000, 5);
      ret.Rows.Add(2, "第二営業部",
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", null),
          1247, "DP00002", "モニター", 25000, 10);
      return ret;
  }

帳票を出力するコード

データの準備ができたので、帳票を出力するコードを書きます。

まずは帳票定義ファイルを読み込んでReportオブジェクトを作成し、 GlobalScopeに値を登録します。 その後、データを投入してページ分割を行います。

  // 帳票定義ファイルを読み込みます
  Report report = new Report(Json.Read("report\\example2.rrpt"));

  // GlobalScopeに値を登録します
  report.GlobalScope.Add("startDate", DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", null));
  report.GlobalScope.Add("endDate", DateTime.ParseExact("2013/02/28", "yyyy/MM/dd", null));
  report.GlobalScope.Add("printDate", DateTime.Today);
  report.GlobalScope.Add("kaisha", "株式会社 システムベース");

  // 帳票にデータを渡します
  report.Fill(new ReportDataSource(getDataTable()));

  // ページ分割を行います
  ReportPages pages = report.GetPages();

PDF出力、Excel(XLS)出力、そしてプレビュー表示を行うコードは以下のようになります。

  // PDF出力
  using (FileStream fs = new FileStream("output\\example2.pdf", FileMode.Create))
  {
      PdfRenderer renderer = new PdfRenderer(fs);
      // バックスラッシュ文字を円マーク文字に変換します
      renderer.Setting.ReplaceBackslashToYen = true;
      pages.Render(renderer);
  }

  // XLS出力
  using (FileStream fs = new FileStream("output\\example2.xls", FileMode.Create))
  {
      HSSFWorkbook workbook = new HSSFWorkbook();
      XlsRenderer renderer = new XlsRenderer(workbook);
      // Renderメソッドを呼ぶ前に必ずNewSheetメソッドを呼んでワークシートを作成します
      renderer.NewSheet("売上明細表");
      pages.Render(renderer);
      workbook.Write(fs);
  }

  // XLSX出力
  using (FileStream fs = new FileStream("output\\example2.xlsx", FileMode.Create))
  {
      XSSFWorkbook workbook = new XSSFWorkbook();
      XlsxRenderer renderer = new XlsxRenderer(workbook);
      // Renderメソッドを呼ぶ前に必ずNewSheetメソッドを呼んでワークシートを作成します
      renderer.NewSheet("売上明細表");
      pages.Render(renderer);
      workbook.Write(fs);
  }

  // 直接印刷、プレビュー画面表示
  {
      Printer printer = new Printer(pages);
      //// 直接印刷
      //// ダイアログを出して印刷します
      //if (printer.PrintDialog.ShowDialog() == System.Windows.Forms.DialogResult.OK)
      //{
      //    printer.PrintDocument.Print();
      //}

      //// ダイアログを出さずに印刷します
      //printer.PrintDocument.Print();

      // プレビュー画面表示
      FmPrintPreview preview = new FmPrintPreview(printer);
      // プレビュー画面が開かれた時点で表示倍率を現在のウィンドウサイズに合わせます
      preview.StartUpZoomFit = true;
      preview.ShowDialog();
  }

VisualBasic

参照設定

VisualBasicでプログラムを作成する前に、いくつかのdllファイルを参照設定に追加する必要があります。 「プログラム開発の準備」に、どのdllを参照すべきかの説明があります。

データの定義

帳票に渡すデータは、DataTableオブジェクトの形式で用意します。 以下に示すように、データの格納されたDataTableを返すメソッドを用意します。

  Private Function getDataTable() As DataTable
      Dim ret As New DataTable
      ret.Columns.Add("bumonCd", GetType(Decimal))
      ret.Columns.Add("bumon", GetType(String))
      ret.Columns.Add("uriageDate", GetType(Date))
      ret.Columns.Add("denpyoNo", GetType(Decimal))
      ret.Columns.Add("shohinCd", GetType(String))
      ret.Columns.Add("shohin", GetType(String))
      ret.Columns.Add("tanka", GetType(Decimal))
      ret.Columns.Add("suryo", GetType(Decimal))
      ret.Rows.Add(1, "第一営業部", _
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", Nothing), _
          1246, "PC00001", "ノートパソコン", 70000, 10)
      ret.Rows.Add(1, "第一営業部", _
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", Nothing), _
          1246, "DP00002", "モニター", 25000, 10)
      ret.Rows.Add(1, "第一営業部", _
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", Nothing), _
          1246, "PR00003", "プリンタ", 20000, 2)
      ret.Rows.Add(1, "第一営業部", _
          DateTime.ParseExact("2013/02/10", "yyyy/MM/dd", Nothing), _
          1248, "PR00003", "プリンタ", 20000, 3)
      ret.Rows.Add(2, "第二営業部", _
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", Nothing), _
          1247, "PC00001", "ノートパソコン", 70000, 5)
      ret.Rows.Add(2, "第二営業部", _
          DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", Nothing), _
          1247, "DP00002", "モニター", 25000, 10)
      Return ret
  End Function

帳票を出力するコード

データの準備ができたので、帳票を出力するコードを書きます。

まずは帳票定義ファイルを読み込んでReportオブジェクトを作成し、 GlobalScopeに値を登録します。 その後、データを投入してページ分割を行います。

  ' 帳票定義ファイルを読込みます
  Dim report As New Report(Json.Read("report\example2.rrpt"))

  ' GlobalScopeに値を登録します
  report.GlobalScope.Add("startDate", DateTime.ParseExact("2013/02/01", "yyyy/MM/dd", Nothing))
  report.GlobalScope.Add("endDate", DateTime.ParseExact("2013/02/28", "yyyy/MM/dd", Nothing))
  report.GlobalScope.Add("printDate", Today)
  report.GlobalScope.Add("kaisha", "株式会社 システムベース")

  ' 帳票にデータを渡します
  report.Fill(New ReportDataSource(getDataTable))

  ' ページ分割を行います
  Dim pages As ReportPages = report.GetPages()

PDF出力、Excel(XLS)出力、そしてプレビュー表示を行うコードは以下のようになります。

  ' PDF出力
  Using fs As New FileStream("output\example2.pdf", IO.FileMode.Create)
      Dim renderer As New PdfRenderer(fs)
      'バックスラッシュ文字を円マーク文字に変換します
      renderer.Setting.ReplaceBackslashToYen = True
      pages.Render(renderer)
  End Using

  ' XLS出力
  Using fs As New FileStream("output\example2.xls", IO.FileMode.Create)
      Dim workbook As New HSSFWorkbook
      Dim renderer As New XlsRenderer(workbook)
      'Renderメソッドを呼ぶ前に必ずNewSheetメソッドを呼んでワークシートを作成します
      renderer.NewSheet("sample2")
      pages.Render(renderer)
      workbook.Write(fs)
  End Using

  ' XLSX出力
  Using fs As New FileStream("output\example2.xlsx", IO.FileMode.Create)
      Dim workbook As New XSSFWorkbook
      Dim renderer As New XlsxRenderer(workbook)
      'Renderメソッドを呼ぶ前に必ずNewSheetメソッドを呼んでワークシートを作成します
      renderer.NewSheet("sample2")
      pages.Render(renderer)
      workbook.Write(fs)
  End Using

  ' 直接印刷、プレビュー画面表示
  With Nothing
      Dim printer As New Printer(pages)

      '' 直接印刷
      '' ダイアログを出して印刷します
      'If printer.PrintDialog.ShowDialog = DialogResult.OK Then
      '  printer.PrintDocument.Print()
      'End If
      '' ダイアログを出さずに印刷します
      'printer.PrintDocument.Print()

      ' プレビュー画面表示
      Dim preview As New FmPrintPreview(printer)
      ' プレビュー画面が開かれた時点で表示倍率を現在のウィンドウサイズに合わせます
      preview.StartUpZoomFit = True
      preview.ShowDialog()
  End With

Java

クラスパスの追加

Javaでプログラムを作成する前に、いくつかのjarファイルをクラスパスに含める必要があります。 「プログラム開発の準備」に、どのjarを含めるべきかの説明があります。

データの定義

以下のように、帳票に渡すデータをDataTable形式で返すメソッドを作成します。

  private static DataTable getDataTable() throws Exception {
      DataTable ret = new DataTable();
      SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
      ret.setFieldNames("bumonCd", "bumon", "uriageDate", "denpyoNo",
          "shohinCd", "shohin", "tanka", "suryo");
      ret.addRecord().puts(1, "第一営業部", sdf.parse("2013/02/01"), 1246,
          "PC00001", "ノートパソコン", 70000, 10);
      ret.addRecord().puts(1, "第一営業部", sdf.parse("2013/02/01"), 1246,
          "DP00002", "モニター", 25000, 10);
      ret.addRecord().puts(1, "第一営業部", sdf.parse("2013/02/01"), 1246,
          "PR00003", "プリンタ", 20000, 2);
      ret.addRecord().puts(1, "第一営業部", sdf.parse("2013/02/10"), 1248,
          "PR00003", "プリンタ", 20000, 3);
      ret.addRecord().puts(2, "第二営業部", sdf.parse("2013/02/01"), 1247,
          "PC00001", "ノートパソコン", 70000, 5);
      ret.addRecord().puts(2, "第二営業部", sdf.parse("2013/02/01"), 1247,
          "DP00002", "モニター", 25000, 10);
      return ret;
  }

帳票を出力するコード

データの準備ができたので、帳票を出力するコードを書きます。

まずは帳票定義ファイルを読み込んでReportオブジェクトを作成し、 GlobalScopeに値を登録します。 その後、データを投入してページ分割を行います。

  // 帳票定義を読込みます
  Report report = new Report(ReadUtil.readJson("report/example2.rrpt"));

  // globalScopeに値を登録します
  SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd");
  report.globalScope.put("startDate", sdf.parse("2013/02/01"));
  report.globalScope.put("endDate", sdf.parse("2013/02/28"));
  report.globalScope.put("printDate", new Date());
  report.globalScope.put("kaisha", "株式会社 システムベース");

  // 帳票にデータを渡します
  report.fill(new ReportDataSource(getDataTable()));

  // ページ分割を行います
  ReportPages pages = report.getPages();  

PDF出力、XLS、XLSX出力を行うコードは以下のようになります。

  // PDF出力
  {
      FileOutputStream fos = new FileOutputStream("output/example2.pdf");
      try {
          PdfRenderer renderer = new PdfRenderer(fos);
          pages.render(renderer);
      } finally {
          fos.close();
      }
  }

  // XLS出力
  {
      FileOutputStream fos = new FileOutputStream("output/example2.xls");
      try {
          HSSFWorkbook workBook = new HSSFWorkbook();
          XlsRenderer renderer = new XlsRenderer(workBook);
          // Renderメソッドを呼ぶ前に必ずNewSheetメソッドを呼んでワークシートを作成します
          renderer.newSheet("売上明細表");
          pages.render(renderer);
          workBook.write(fos);
      } finally {
          fos.close();
      }
  }

  // XLSX出力
  {
      FileOutputStream fos = new FileOutputStream("output/example2.xlsx");
      try {
          XSSFWorkbook workBook = new XSSFWorkbook();
          XlsxRenderer renderer = new XlsxRenderer(workBook);
          // Renderメソッドを呼ぶ前に必ずNewSheetメソッドを呼んでワークシートを作成します
          renderer.newSheet("売上明細表");
          pages.render(renderer);
          workBook.write(fos);
      } finally {
          fos.close();
      }
  }