レポート実行時にサブレポートにデータを設定
実際の帳票開発においては、SQL Serverなどのデータベースに格納されたデータではなく、コードで動的に生成したデータをもとにレポートを作成したいケースがあります。ActiveReportsでは、セクションレポート/ページレポートと同様、RDLレポートでもこのケースに対応できます。
レポート実行時に動的にデータを設定するには、データソースの種類に「DataSet Provider」を設定したうえで、レポートのLocateDataSourceイベントでレポートにデータ(DataTable)を設定します。詳細については、製品ヘルプの[実行時にレポートとデータソースの連結]をご参照ください。
ここでは、メインレポートおよびサブレポートにそれぞれ動的にデータを設定する方法を紹介します。サンプルとして、「自然数とその約数を表示する」レポートを作成します。
付属のサンプルは、「04_レポート実行時にサブレポートにデータを設定_Main.rdlx」および、「04_レポート実行時にサブレポートにデータを設定_Sub.rdlx」をご参照ください。
データの作成
はじめに、レポートで使用するデータ(DataTable)を用意します。
メインレポート用に、1から10までの自然数を含むDataTableを作成します。
' メインレポート用の実行時データソース Private Function MakeNaturalNumberTable() As DataTable Dim table As New DataTable table.Columns.Add("NaturalNumber") For i As Integer = 1 To 10 Dim row As DataRow = table.NewRow row("NaturalNumber") = i table.Rows.Add(row) Next Return table End Function
// メインレポート用の実行時データソース private System.Data.DataTable MakeNaturalNumberTable() { DataTable table = new DataTable(); table.Columns.Add("NaturalNumber"); for (int i = 1; i <= 10; i++) { DataRow row = table.NewRow(); row["NaturalNumber"] = i; table.Rows.Add(row); } return table; }
サブレポート用に、1から10までの自然数および、その約数を含むDataTableを作成します。
' サブレポート用の実行時データソース Private Function MakeDivisorTable() As DataTable Dim table As New DataTable table.Columns.Add("NaturalNumber") table.Columns.Add("Divisor") For i As Integer = 1 To 10 For j As Integer = 1 To i If i Mod j = 0 Then Dim row As DataRow = table.NewRow row("NaturalNumber") = i row("Divisor") = j table.Rows.Add(row) End If Next Next Return table End Function
// サブレポート用の実行時データソース private DataTable MakeDivisorTable() { DataTable table = new DataTable(); table.Columns.Add("NaturalNumber"); table.Columns.Add("Divisor"); for (int i = 1; i <= 10; i++) { for (int j = 1; j <= i; j++) { if (i % j == 0) { DataRow row = table.NewRow(); row["NaturalNumber"] = i; row["Divisor"] = j; table.Rows.Add(row); } } } return table; }
データの設定
次に、メインレポートおよびサブレポートに各データ(DataTable)を設定します。具体的には、LocateDataSourceイベントの引数を利用してレポート名を参照し、レポートに応じて必要なデータを設定します。
Private Sub pDoc_LocateDataSource(ByVal sender As Object, ByVal args As GrapeCity.ActiveReports.LocateDataSourceEventArgs) Select Case args.Report.PageReport.Report.Name Case "04_レポート実行時にサブレポートにデータを設定_Sub" args.Data = Me.MakeDivisorTable() Case "" args.Data = Me.MakeNaturalNumberTable() Case Else args.Data = New System.Data.DataTable() End Select End Sub
void pageDocument_LocateDataSource(object sender, GrapeCity.ActiveReports.LocateDataSourceEventArgs args) { switch (args.Report.PageReport.Report.Name) { case "04_レポート実行時にサブレポートにデータを設定_Sub": args.Data = MakeDivisorTable(); break; case "": args.Data = MakeNaturalNumberTable(); break; default: args.Data = new DataTable(); break; } }
LocateDataSourceイベントは、メインレポートおよびサブレポートの実行時にそれぞれ呼び出されます。どのレポートに対して呼び出されたかはargv.Report.PageReport.Report.Nameの値で判定できます。メインレポートの場合は、空文字列になります。上記コードでは2番目の条件に該当し、メインレポート用のDataTableを渡しています。サブレポートの場合は、そのレポート名になります。上記コードでは1番目の条件に該当し、”04_レポート実行時にサブレポートにデータを設定_Sub”がサブレポートの名称なので、サブレポート用のDataTableを渡しています。それ以外の場合は、念のために空のDataTableを渡しておきます。
以上の手順で、サブレポートにデータを渡すことができました。しかしこのままでは、1の約数だけを表示したいのに、1~10までの数の約数がすべて表示されてしまいます。先ほどの例でパラメータを介さない場合と同様の結果になります。
このサブレポートで使っているデータソースはDataSet Providerのため、クエリは使用していません。そのため、この場合には、フィルタを使用してデータを抽出します。
フィルタの追加
まずは、サブレポートにパラメータを追加します。次に、「データセット」ダイアログで「フィルタ」ページを開き、追加したパラメータを利用してデータを抽出します。「フィルタ」ページでフィルタを追加し、「式」には、条件として使いたいフィールド名を指定します。「演算子」には「Equal」、「値」にはパラメータを指定します。
備考
式の値は短縮形で表示されることに気をつけてください。式の値は直接編集せずに、式エディタを使って設定するほうが便利です。式の詳細については、以前の記事(5分でわかるActiveReports帳票(2013年度版)-ページレポートにおけるグループ化と式)をご参照ください。
フィルタの追加によって、SQLクエリに「WHERE ~ = ~」と記述するのと同じような効果が得られます。また、メインレポートには、先ほどと同様にSubReportコントロールにパラメータを追加しておきます。以上の設定により、各自然数ごとの約数が表示されるようになります。
まとめ
今回は、9.0Jの新しいレポート形式であるRDLレポートを紹介しました。RDLレポートの特長であるマルチデータソースおよびサブレポートを活用することで、帳票を柔軟に作成することが可能になります。
次回は、「レイヤー」機能を活用したレポートレイアウトの作成方法を紹介します。