計算や集計を行う
ActiveReports for .NETでは、データベースから取得したデータの集計や加工を行う方法が、いくつか提供されています。それは、データの構成やレポートのレイアウトによって方法が異なってきます。DataInitialize、FetchData、BeforePrintの各イベント、SummaryXXXX、DataFieldの各プロパティが、集計処理を行うために重要となります。また、グルーピングや改ページなどのレイアウトはNewPage、KeepTogether、GroupKeepTogetherなどのプロパティに影響されます。
複数のテーブルを持ったDataSetのデータを表示する
通常、1つのレポートレイアウトファイルは、1つのテーブルのみを参照することができます。複数のテーブルを1つの帳票に出力する方法としては、サブレポートを使用する方法がございます。
テーブル内のフィールドとリレーションをもつ別のテーブル内のデータを取得し、1つの帳票内に出力することができます。詳細については、製品付属の[サブレポート サンプル]内の「サブレポートを使用して複数のテーブルを持ったDataSetを表示する」などをご参照ください。
データが1件も存在しない場合の処理
バウンドレポートとアンバウンドレポートのどちらを作成するかによって、処理が異なります。
データが存在しない場合には、NoDataイベントが発生します。
    NoDataイベント内でCancelメソッドを実行することで、レポートの生成処理をキャンセルし、ページヘッダ/フッタのみのレポートが出力されることを回避することが可能です。
Visual Basic
| Visual Basic コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
Private Sub SectionReport1_NoData(sender As Object, e As System.EventArgs) Handles MyBase.NoData  
    Me.Cancel()  
End Sub
                         | 
                    |
C#
| C# コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
private void SectionReport1_NoData(Object sender, System.EventArgs e)
{
    this.Cancel();
}
                         | 
                    |
Cancelメソッドによりレポートの生成処理がキャンセルされた場合、CurrentPageプロパティがNothingのままになりますので、下記のコードのような処理でデータが無かったことを判断することが可能です。
Visual Basic
| Visual Basic コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
Dim rpt As New SectionReport1  
rpt.Run()  
If (rpt.CurrentPage Is Nothing)
    Then  
    Console.WriteLine("データが存在しません。")  
End If
                         | 
                    |
C#
| C# コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
SectionReport1 rpt = new SectionReport1();  
rpt.Run();  
if (rpt.CurrentPage == null)  
{  
    Console.WriteLine("データが存在しません。");  
}
                         | 
                    |
レポート生成(Runメソッドを実行)前に、データベース接続を行いデータが存在するかどうかを判定します。存在しない場合に、必要な処理を行ってください。
Visual Basic
| Visual Basic コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
Dim m_cnnString As String  
Dim sqlString As String  
Dim m_cnn As System.Data.OleDbOleDb.OleDbConnection  
Dim m_reader As System.Data.OleDbOleDb.OleDbDataReader  
Private Sub Form1_Load(ByVal sender As _
System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
    Dim rpt As New SectionReport1()  
    m_cnnString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source= ..Data\\Nwind.mdb; Persist Security Info=False"  
    SqlString = "SELECT * FROM Products where ProductID = 100"  
    m_cnn = New OleDb.OleDbConnection(m_cnnString)  
    Dim m_Cmd As New OleDb.OleDbCommand(SqlString, m_cnn)  
    If m_cnn.State = ConnectionState.Closed 
        Then  
        m_cnn.Open()  
    End If  
    m_reader = m_Cmd.ExecuteReader()  
    If m_reader.Read = False
        Then  
        MessageBox.Show("データが存在しません。")  
    Else  
        m_reader.Close()  
        m_reader = m_Cmd.ExecuteReader()  
        Me.Viewer1.Document = rpt.Document  
        rpt.Run()  
    End If  
End Sub
                         | 
                    |
C#
| C# コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
private static System.Data.OleDb.OleDbConnection m_cnn;  
private static System.Data.OleDb.OleDbDataReader m_reader;  
private void Form1_Load(object sender, EventArgs e)  
{  
    SectionReport rpt = new SectionReport();  
    string m_cnnString = "Provider=Microsoft.Jet.OLEDB.4.0; Data Source=..Data\\Nwind.mdb; Persist Security Info=False";  
    string sqlString = "SELECT * FROM Products where ProductID = 100";  
    m_cnn = new System.Data.OleDb.OleDbConnection(m_cnnString);  
    System.Data.OleDb.OleDbCommand m_Cmd = new System.Data.OleDb.OleDbCommand(sqlString, m_cnn);  
    if (m_cnn.State == ConnectionState.Closed)  
    {  
        m_cnn.Open();  
    }  
    m_reader = m_Cmd.ExecuteReader();  
    if (m_reader.Read() == false)  
    {  
        MessageBox.Show("データが存在しません。");  
    }  
    else  
    {  
        m_reader.Close();  
        m_reader = m_Cmd.ExecuteReader();  
        this.viewer1.Document = rpt.Document;  
        rpt.Run();  
    }  
}
                         | 
                    |
ページヘッダに次レコードのデータが出力される
ページヘッダセクションは基本的に、各ページの先頭に表示する必要のあるカラムヘッダやページ番号、またはページタイトルといった、レコードの内容に関係しない情報を出力します。ページヘッダやページフッタ上に、レコードごとに値が変化するバウンドコントロール(データベースに連結したコントロール)を配置することはお勧めしません。
改ページやグループの切り替わりは該当レコードを読み込むまで判断できない為、改ページ時やグループ変化時にはデータの先読みが発生します。このような理由から、ページヘッダにレコードのデータを出力しているような場合には、そのページの1レコード目ではなく2レコード目の内容が出力される場合があります。
レコードの内容を各ページの先頭に表示したい場合には、ページヘッダセクションではなくグループヘッダセクションを使用します。グループヘッダセクションの RepeatStyle プロパティを OnPage や OnPageIncludeNoDetail に設定することで、グループヘッダセクションは各ページの先頭に出力されます。
重複したデータを非表示にする
セクションが描画される直前に発生するBeforePrintイベントや、描画された後に発生するAfterPrintイベントを利用することで、重複データの非表示動作が可能です。
たとえば下記のコードでは、重複データは非表示にした上で、各ページの描画処理が完了したときに発生するPageEndイベントを利用し、改ページ後最初のデータは必ず出力するようにしています。こちらを参考にご検討ください。
Visual Basic
| Visual Basic コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
Dim strBuff As String
Private Sub Detail1_BeforePrint(sender As System.Object, e As System.EventArgs) Handles Detail1.BeforePrint
    strBuff = ""
    If (TextBox1.Text <> strBuff)
        Then
        TextBox1.Visible = True
    Else
        ' 重複データは非表示にします。
        TextBox1.Visible = False
    End If
    strBuff = TextBox1.Text
End Sub
Private Sub ActiveReport1_PageEnd(ByVal sender As Object, ByVal e As System.EventArgs) Handles MyBase.PageEnd
    ' 改ページ後、最初のデータは必ず出力します。
    strBuff = ""
End Sub
                         | 
                    |
C#
| C# コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
string strBuff;
private void Detail_BeforePrint(object sender, System.EventArgs eArgs)
{
    strBuff = "";
    if (TextBox1.Text != strBuff)
    {
        TextBox1.Visible = true;
    }
    else
    {
        // 重複データは非表示にします。
        TextBox1.Visible = false;
    }
    strBuff = TextBox1.Text;
}
private void rptSimpleGroup_PageEnd(object sender, System.EventArgs eArgs)  
{
    // 改ページ後、最初のデータは必ず出力します。
    strBuff = "";
}
                         | 
                    |
ODBCデータ ソースを使用する
設計時に直接ODBCデータソースをレポートに設定することができます。ODBCデータソースに接続する前に、ODBCドライバをインストールしてODBCデータソースを設定する必要があります。詳細については、「レポートとデータソースの連結」を参照してください。
また、実行時に .NET Framework Data Provider for ODBCを使用してデータソースを取得する方法で使用することができます。[プロジェクト] メニューの [参照の追加] をクリックし、System.Data.ODBCに対する参照を設定します。
Visual Basic
| Visual Basic コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
Private Sub SectionReport1_ReportStart(sender As System.Object, e As System.EventArgs) Handles MyBase.ReportStart
    ' データベースと連結します。
    Dim m_cnn As OdbcConnection
    Dim m_cnnString As String = ("Dsn=Nwind;trusted_connection=Yes;app=Microsoft® Visual Studio® 2010;wsid=SystemID;database=Northwind")
    Dim sqlString As String = "SELECT * FROM Products"
    m_cnn = New OdbcConnection(m_cnnString)
    Dim m_Cmd As OdbcCommand = New OdbcCommand(sqlString, m_cnn)
    m_cnn.Open()
    ' DataReaderと連結します。
    Dim m_reader As OdbcDataReader
    m_reader = m_Cmd.ExecuteReader()
    Me.DataSource = m_reader
End Sub
                         | 
                    |
C#
| C# コード | 
                             
                                コードのコピー
                             
                         | 
                    
|---|---|
                            
private void SectionReport1_ReportStart(object sender, EventArgs e)
{
    // データベースと連結します。
    OdbcConnection m_cnn = default(OdbcConnection);
    string m_cnnString = ("Dsn=Nwind;trusted_connection=Yes;app=Microsoft® Visual Studio® 2010;wsid=SystemID;database=Northwind");
    string sqlString = "SELECT * FROM Products";
    m_cnn = new OdbcConnection(m_cnnString);
    OdbcCommand m_Cmd = new OdbcCommand(sqlString, m_cnn);
    m_cnn.Open();
    // DataReaderと連結します。
    OdbcDataReader m_reader = default(OdbcDataReader);
    m_reader = m_Cmd.ExecuteReader();
    this.DataSource = m_reader;
}
                         | 
                    |
レポートのデータソースにストアドプロシージャを使用する
ActiveReportsから直接ストアドプロシージャを呼び出すことはできません。しかしながら、ActiveReportオブジェクトのDataSourceプロパティには、.NET FrameworkのDataSetをセットできます。あらかじめ、DataSetにストアドプロシージャの結果セットを格納しておき、それをActiveReportオブジェクトDataSourceプロパティにセットすることで、ストアドプロシージャで取得したデータを元に、レポートを作成できます。
DataSetをデータソースとしてレポートを作成する方法については、「サブレポート サンプル」を参照してください。
DataSetの作成方法については、マイクロソフト社のWebサイトで公開しているサポート技術情報をご覧ください。
CSVや配列データを元にレポートを作成する
ActiveReportsの基本的なレポート生成方法には、データソースとレポートを直接接続するバウンドレポートと、コード上でデータをセットするアンバウンドレポートがあります。
バウンドレポートの場合、.NET Framework標準の下記データソースとの接続が可能です。
たとえば、ArrayListクラスは、IListインターフェイスを実装していますので、CSVファイルや、配列に格納されたデータをあらかじめArrayListに格納しておけば、これをレポートのデータソースとして使用することが可能です
アンバウンドレポートの場合、データソースへの接続やレコードの移動、データのセット等の処理は、すべてコードで行うことになりますので、一般的なデータソース以外にも、たとえばテキストファイルや配列に格納されたデータなど、さまざまなデータを元にレポートを生成することが可能です。
詳細情報は、製品付属の「IListバインドサンプル」および「アンバウンドサンプル」を参照してください。
パラメータ付きレポートを実行すると、「System.Data...」例外が発生する
パラメータ付きレポートを実行すると、'System.Data.OleDb.OleDbException'のハンドルされていない例外が発生します。
レポートをアクセスデータベースに接続したとき、パラメータを含むSQLクエリで日付フィールドの場合は「#」、または、文字列フィールドの場合は引用符を設定する必要があります。詳細は、以下のSQLクエリをご参照ください。
| SQLクエリ | 
                         
                            コードのコピー
                         
                     | 
                
|---|---|
                        #%InvoiceDate | Choose invoice date: | 11/2/04 | D | True%#  | 
                |
または、
| SQLクエリ | 
                         
                            コードのコピー
                         
                     | 
                
|---|---|
                        "%Country | Country: | Germany | S | True%"  | 
                |
パラメータを設定すると、レポートエクスプローラのフィールドにエラーが発生する
SQLクエリでパラメータを設定するときデフォルト値が設定されていない場合は、レポートエクスプローラのテキスト型フィールドおよび日付型フィールドでエラーが発生します。以下の構文をSQLクエリに設定し、エラーを回避できます。
| SQLクエリ | 
                         
                            コードのコピー
                         
                     | 
                
|---|---|
                        %Name | PromptString | DefaultValue | DataType | PromptUser%  | 
                |
または、
| SQLクエリ | 
                         
                            コードのコピー
                         
                     | 
                
|---|---|
                        %Name | | DefaultValue | |%  | 
                |
該当レコードまでの累積値を出力する
以下のように、該当レコードまでの累積値(累計)を表示する方法は、レポートの形式によって異なります。
| データ | 累積値 | 
|---|---|
| 10 | 10 | 
| 20 | 30 | 
| 30 | 60 | 
| 40 | 100 | 
| 50 | 150 | 
TextBoxコントロールの集計機能(Summary***プロパティ)を Detailセクション上に配置することで、その行(レコード)までの累積値を出力できます。
出力したい値に応じてTextBoxコントロールの各プロパティを以下のように設定してください。
    ◆レポート全体の累積値を出力する場合
 
  DataField = (対象のフィールド名)
     SummaryFunc = Sum
     SummaryGroup = (空白)
     SummaryRunning = Group または All
     SummaryType = GrandTotal
    ◆グループ単位の累積値を出力する場合
 DataField = (対象のフィールド名)
     SummaryFunc = Sum
     SummaryGroup = (対象グループのグループヘッダ名)
     SummaryRunning = Group または All
     SummaryType = SubTotal
レポートのデータソース(接続文字列やSQL文など)を動的に変更する
セクションレポートのデータソースは、レポートの作成前(Runメソッド実行前またはReportStartイベント内)に動的に設定することが可能です。