Shoeisha Technology Media

CodeZine(コードジン)

特集ページ一覧

5分でわかるActiveReports帳票-RDLレポート

ActiveReports for .NET 9.0Jで作るサンプル帳票(2)

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

 本連載では、帳票コンポーネント「ActiveReports for .NET 9.0J」の新機能を使用して帳票アプリケーションを作成する方法を解説します。第2回の今回は、9.0Jで追加された新しいレポート形式であるRDLレポートの使い方を紹介します。

備考

 ActiveReportsを使用した帳票アプリケーションの基本的な作成方法については、これまでの連載記事も併せてご参照ください。特に、1つ前のバージョンである7.0Jをもとに解説した2013年度版の記事は、9.0Jでもそのままご利用いただける内容となっています。また、2007/2008年度版の記事は3.0Jをもとに解説していますが、3.0Jのレポートと9.0Jのセクションレポートは名前空間や一部のAPIを除いて同じレポート形式であるため、セクションレポートの概念や基本的な使い方についてはこちらもご活用ください。

対象読者

  • Visual Basicまたは、Visual C#を使ってプログラムを作ったことのある方
  • 帳票作成ツールに興味のある方

必要な環境

  • Visual Studio 2010/2012/2013/2015のいずれかでプログラムが作れる環境
    • Express EditionではActiveReportsをインストールできません。また、Visual Studio 2015についてはService Pack 2で対応しています。

 本記事のサンプルコードは、C# 5.0/Visual Basic 2012で記述しています。

ActiveReports for .NET 9.0Jのインストール

 今回はじめてActiveReportsを使用する方は、まず開発用PCにActiveReportsをインストールする必要があります。ActiveReportsは有償の製品ですが、トライアル版(無償)が用意されています。グレープシティのWebページからダウンロードできますので、ここからダウンロードしてインストールしてください(インストール時の注意事項については、こちらのナレッジ文書をご参照ください)。

 ActiveReportsにはStandardとProfessionalの2つのエディションがありますが、今回はProfessionalをインストールします。各エディションの違いについては、こちらのナレッジ文書をご参照ください。

コントロールの追加

 インストール後は、すぐに帳票アプリケーションの開発を始められるようになっていますが、効率のよいアプリケーション開発のために、Visual StudioのツールボックスにActiveReportsのコントロールを追加しておきましょう。

 ツールボックスにコントロールを追加するには、メニューバーの[ツール]-[ツールボックスアイテムの選択]をクリックします。「ツールボックスアイテムの選択」ダイアログが表示されるので、追加したいコントロールにチェックを入れて[OK]ボタンを押します。詳しい手順については、製品ヘルプの[クイックスタート]-[ActiveReportsコントロールを追加する]をご参照ください。

ツールボックスにActiveReportsのコントロールを追加
ツールボックスにActiveReportsのコントロールを追加

 同じ端末に異なるバージョンのActiveReportsがインストールされていると、「ツールボックスアイテムの選択」ダイアログに、複数バージョンのコントロールが表示されます。1つのプロジェクトに、異なるバージョンのコントロールを混在させるとエラーが発生します。同じ端末に異なるバージョンのActiveReportsを共存させている場合は、バージョンをインストーラやリリースノートから確認し、コントロール使用時にバージョンが混在しないように注意してください(バージョンの詳しい確認方法については、こちらのナレッジ文書をご参照ください)。

RDLレポートのデザイン方式

 RDLレポートのレポート生成エンジンは、ページレポートと同じものを使用しています。このため、RDLレポートのデザイナで使用できるデータ領域やレポートアイテムは、ページレポートとほぼ共通となっています。

 一方で、デザイン方式は大きく異なります。ページレポートがページ単位で帳票を作成するのに対して、RDLレポートはページを意識せずに自由にデータを表示します。このデザイン方式の違いは、データ領域のFixedSizeプロパティの有無にはっきりと表れています。たとえば、Tableデータ領域をレポート上に配置すると、ページレポートではFixedSizeの領域(斜線の部分)が表示されているのに対して、RDLレポートではFixedSizeは表示されません。

ページレポートのTableデータ領域
ページレポートのTableデータ領域
RDLレポートのTableデータ領域
RDLレポートのTableデータ領域

 また、RDLレポートのデータ領域はデータ数に応じて伸長し、印刷の用紙サイズに収まりきらなくなった場合には、次ページに引き続きデータが表示されます。この動作は、固定レイアウトでページを作成するページレポートとは異なり、むしろセクションレポートに近いデザイン方式と言えます。なお、RDLレポートのデザイン方式の詳細については、技術資料「3つの帳票デザイン方式」(PDFファイル)をご参照ください。

簡単なRDLレポートの作成

 それでは、簡単なRDLレポートを作ってみましょう。以前の記事(5分でわかるActiveReports帳票(2013年度版)-ページレポート)で、簡単なページレポートを作成しました。これと同じものをRDLレポートで実現してみます。なお、RDLレポートの作成は、ページレポートと共通する部分が多いため、適宜こちらの記事をご参照ください。

 はじめに、RDLレポートをプロジェクトに追加します。ソリューションエクスプローラーでプロジェクトを右クリックして、[追加]-[新しい項目]から[ActiveReports 9.0J RDLレポート(XML)]を選択します。RDLレポートがプロジェクトに追加され、レポートのデザイン画面が開きます。

 付属のサンプルは、「01_簡単なRDLレポートの作成.rdlx」をご参照ください。

データセットの追加

 レイアウトを作成する前に、データソースとデータセットを追加します。これは、ページレポートと同様、レポートエクスプローラから追加します。

レイアウトの作成

 次に、レポート上にデータ領域を配置します。以前の記事のページレポートではListデータ領域を使いましたが、今回はBandedListデータ領域を使用します。これは、BandedListのヘッダ/フッタをページヘッダ/ページフッタとして使用するためです。

 BandedList上にTextBoxを配置し、それぞれのValueプロパティを設定してデータソースと結びつけます。

プレビュー表示

 レポートをプレビュー表示するには、ViewerコントロールのLoadDocument()メソッドでPageDocumentオブジェクトを読み込みます。この手順も、ページレポートと同様です。

プレビュー表示
プレビュー表示

ゲラモード

 RDLレポートでは、印刷時の用紙サイズを考慮した従来の印刷プレビューモードに加えて、すべてのデータを1ページとして閲覧できるゲラモードを用意しています。改ページなしですべてのデータを確認できるため、Matrixデータ領域を使用した横に伸びるレポートの閲覧や、データ件数の多いレポートのプレビューに適しています。

  

クロス集計表(印刷プレビュー)
クロス集計表(印刷プレビュー)

 印刷プレビューモードでは、印刷時の用紙サイズに合わせて、ページ余白の追加および改ページがされた状態で表示されます。

クロス集計表(ゲラモード)
クロス集計表(ゲラモード)

 一方、ゲラモードでは、改ページなしですべてのデータを1ページに表示します。なお、印刷プレビューモードとゲラモードは、Viewerコントロールのツールバーで簡単に切り替えできます。

 上記サンプルは、ActiveReportsのオンラインデモを使用しています。[RDLレポートギャラリー]-[クロス集計表]から実際の動作をご確認いただけます。

マルチデータソース

 RDLレポートでは、複数のデータソースおよびデータセットを使用できます。

 ここでは、マルチデータソースのレポートサンプルとして、異なる2つのデータセットを表示するレポートを作成します。

 付属のサンプルは、「02_マルチデータソース.rdlx」をご参照ください。

マルチデータソースのレポート
マルチデータソースのレポート

データセットの作成

 RDLレポートを追加し、レポートエクスプローラから、[データソースの追加]を選択します。データソースには、製品付属のNwind.mdbデータベースを使用します。次に、[データセットの追加]を選択し、Productsテーブルから商品一覧を抽出するSQLクエリを記述します。

SELECT Products.ProductName, Products.CategoryID, Categories.CategoryName FROM Products INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID

 さらに、もう一つのデータソースを追加します。同様に、Nwind.mdbデータベースを使用します(注1)。また、データセットを追加し、商品種類(カテゴリ)ごとの品数を抽出するSQLクエリを記述します。

SELECT Categories.CategoryName, COUNT(ProductID) AS Item FROM Products INNER JOIN Categories ON Products.CategoryID = Categories.CategoryID GROUP BY Products.CategoryID, Categories.CategoryName

注1

 この場合はデータソースとしては同じであるため、1つのデータソースに2つのデータセットを追加してもかまいません。

 レポートのデザイン画面を開き、2つのTableデータ領域を横に配置します。

2つのデータ領域を配置する
2つのデータ領域を配置する

データセットの設定

 データセットが複数あるレポートでは、データ領域ごとにどのデータセットを使うかを指定する必要があります。各Tableデータ領域を選択した状態でプロパティダイアログを開き、「データセット名」に使用するDataSetの名前を設定します。

データセットの指定
データセットの指定

 データセット名を指定したら、デザイン画面でTableデータ領域の各セルにバインドするフィールドを設定します。

サブレポートの使用

 マルチデータソース対応に加えて、RDLレポートではサブレポートを使用できます。サブレポートとは、別のレポート内に挿入されているレポートのことです。例えば、プロジェクトに2つのレポート(メインレポートおよびサブレポート)を追加し、メインレポート上にSubReportコントロールを配置することで、そこにサブレポートを表示できます。

 サブレポートを使用する場合、メインレポート上に直接配置する場合も考えられますが、実際のケースでは、メインレポートのデータ領域の中にサブレポートを配置する方法が多いと思われます。なお、メインレポートとサブレポートのデータ連結には、パラメータを使用します。

 ここでは、サブレポートを使ったサンプルとして、見積書を作成します。データソースには、製品付属のSeikyu2.mdbデータベースを使用します。

 付属のサンプルは、「03_サブレポートの使用_Main.rdlx」および、「03_サブレポートの使用_Sub.rdlx」をご参照ください。

データセットの作成

 メインレポートのデータセットとして、見積IDと顧客名をグループ化したデータを取得します。

メインレポートのデータセット
SELECT Estimate.EstimateID, Customers.CompanyName FROM Estimate INNER JOIN Customers ON Estimate.CustomerID = Customers.CustomerID GROUP BY Estimate.EstimateID,Customers.CompanyName

 サブレポートのデータセットとして、品名と個数の詳細データを取得します。

サブレポートのデータセット
SELECT Estimate.EstimateID, Products.ProductName, Estimate.Quantity FROM Estimate INNER JOIN Products ON Estimate.ProductID = Products.ProductID

レイアウトの作成

 メインレポートにTableデータ領域を配置し、Tableデータ領域内に、顧客名を表示するTextBoxレポートアイテムおよびSubReportレポートアイテムを配置します。

メインレポートのデザイン画面
メインレポートのデザイン画面

 サブレポートにTableデータ領域を配置し、品名および個数を表示するTextBoxレポートアイテムを配置します。

サブレポートのデザイン画面
サブレポートのデザイン画面

サブレポートの指定

 レポートデザインが完成したら、メインレポートとサブレポートを関連付けます。メインレポートに配置したSubReportコントロールのReportNameプロパティにサブレポート名を設定します。

 さて、この状態で試しにレポートをプレビューしてみると、本来ならば顧客ごとの注文内容を表示したいのですが、すべての顧客の注文内容が表示されてしまいます。

サブレポートにすべての詳細が表示される
サブレポートにすべての詳細が表示される

パラメータの追加

 顧客ごとの注文内容を表示するためには、パラメータを使用してデータを抽出します。

 サブレポートを開き、レポートエクスプローラからパラメータを追加します。パラメータの名前は、デフォルトの「ReportParameter1」でかまいません。次に、サブレポートのデータセットのダイアログで「パラメータ」ページを開いて、パラメータを追加します。パラメータの値には、先ほどレポートに追加した「ReportParameter1」を設定します。

データセットにパラメータを追加する
データセットにパラメータを追加する

 次に、パラメータとデータセットに結びつけるために、SQLクエリを修正します。データセットのEstimateIDが特定の値の時だけのデータ行を抽出するよう、クエリの最後に「WHERE EstimateID = ?」と追加します。

SELECT Estimate.EstimateID, Products.ProductName, Estimate.Quantity FROM Estimate INNER JOIN Products ON Estimate.ProductID = Products.ProductID WHERE EstimateID = ?

備考

 ここでは、データソースの種類がOleDBのため、クエリ中のパラメータ表現として「?」を使っています。記述方法はデータソースの種類で異なります。詳細については、製品ヘルプの[パラメータ]をご参照ください。

 最後に、メインレポートに配置したSubReportコントロールの「Parameters」プロパティを開き、パラメータを追加します。「パラメータ名」には先ほどサブレポートに追加した「ReportParameter1」、「パラメータ値」には渡したいフィールドを指定します。

SubReportコントロールにパラメータを設定する
SubReportコントロールにパラメータを設定する

 以上のパラメータの設定により、顧客ごとの注文内容が表示されるようになります。

パラメータを使用したレポート
パラメータを使用したレポート

レポート実行時にサブレポートにデータを設定

 実際の帳票開発においては、SQL Serverなどのデータベースに格納されたデータではなく、コードで動的に生成したデータをもとにレポートを作成したいケースがあります。ActiveReportsでは、セクションレポート/ページレポートと同様、RDLレポートでもこのケースに対応できます。

 レポート実行時に動的にデータを設定するには、データソースの種類に「DataSet Provider」を設定したうえで、レポートのLocateDataSourceイベントでレポートにデータ(DataTable)を設定します。詳細については、製品ヘルプの[実行時にレポートとデータソースの連結]をご参照ください。

 ここでは、メインレポートおよびサブレポートにそれぞれ動的にデータを設定する方法を紹介します。サンプルとして、「自然数とその約数を表示する」レポートを作成します。

 付属のサンプルは、「04_レポート実行時にサブレポートにデータを設定_Main.rdlx」および、「04_レポート実行時にサブレポートにデータを設定_Sub.rdlx」をご参照ください。

データの作成

 はじめに、レポートで使用するデータ(DataTable)を用意します。

 メインレポート用に、1から10までの自然数を含むDataTableを作成します。

メインレポートのDataTable(VB.NET)
' メインレポート用の実行時データソース
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
メインレポートのDataTable(C#)
// メインレポート用の実行時データソース
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を作成します。

サブレポートのDataTable(VB.NET)
' サブレポート用の実行時データソース
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
サブレポートのDataTable(C#)
// サブレポート用の実行時データソース
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イベントの引数を利用してレポート名を参照し、レポートに応じて必要なデータを設定します。

実行時にデータソースを渡す(VB.NET)
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
実行時にデータソースを渡す(C#)
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レポートの特長であるマルチデータソースおよびサブレポートを活用することで、帳票を柔軟に作成することが可能になります。

 次回は、「レイヤー」機能を活用したレポートレイアウトの作成方法を紹介します。

  • ブックマーク
  • LINEで送る
  • このエントリーをはてなブックマークに追加

著者プロフィール

All contents copyright © 2005-2019 Shoeisha Co., Ltd. All rights reserved. ver.1.5