備考
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がインストールされていると、「ツールボックスアイテムの選択」ダイアログに、複数バージョンのコントロールが表示されます。1つのプロジェクトに、異なるバージョンのコントロールを混在させるとエラーが発生します。同じ端末に異なるバージョンのActiveReportsを共存させている場合は、バージョンをインストーラやリリースノートから確認し、コントロール使用時にバージョンが混在しないように注意してください(バージョンの詳しい確認方法については、こちらのナレッジ文書をご参照ください)。
RDLレポートのデザイン方式
RDLレポートのレポート生成エンジンは、ページレポートと同じものを使用しています。このため、RDLレポートのデザイナで使用できるデータ領域やレポートアイテムは、ページレポートとほぼ共通となっています。
一方で、デザイン方式は大きく異なります。ページレポートがページ単位で帳票を作成するのに対して、RDLレポートはページを意識せずに自由にデータを表示します。このデザイン方式の違いは、データ領域のFixedSizeプロパティの有無にはっきりと表れています。たとえば、Tableデータ領域をレポート上に配置すると、ページレポートではFixedSizeの領域(斜線の部分)が表示されているのに対して、RDLレポートではFixedSizeは表示されません。


また、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データ領域を横に配置します。

データセットの設定
データセットが複数あるレポートでは、データ領域ごとにどのデータセットを使うかを指定する必要があります。各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」、「パラメータ値」には渡したいフィールドを指定します。

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

レポート実行時にサブレポートにデータを設定
実際の帳票開発においては、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レポートの特長であるマルチデータソースおよびサブレポートを活用することで、帳票を柔軟に作成することが可能になります。
次回は、「レイヤー」機能を活用したレポートレイアウトの作成方法を紹介します。