SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

5分でわかるActiveReports帳票

5分でわかるActiveReports帳票-改ページ制御と多段組レイアウト(2007年度版)

ActiveReports for .NET 3.0Jで作るサンプル帳票

  • X ポスト
  • このエントリーをはてなブックマークに追加

ダウンロード 使用データ (1013.0 B)

カラムを使った多段組レイアウト 2

SubReportコントロールで行ヘッダを作成する

 今回の帳票で1番左側に表示する商品名列は、表示される値が決まっていれば直接Labelコントロールなどに書いて並べてもよいのですが、ここではSubReportコントロールを使って、表示される値が可変の商品名列を作成する方法を紹介します。

 ActiveReportsのSubReportコントロールを使うと、レポート内に別のレポート(子レポート)を埋め込んで使うことができます。子レポートの出力は親レポートのセクションが出力されるたびに実行されます。

 子レポートは、普通のActiveReports帳票を作成するのと同じ方法で作成します。プロジェクトに新しいActiveReports 3.0ファイルを追加し、親レポートと同様にグループヘッダ、detail、グループフッタセクションをもつ小さな帳票を作成します。

子レポートの帳票レイアウト
子レポートの帳票レイアウト

 次に、作成した子レポートを親レポートに埋め込みます。親レポートの商品名グループヘッダに、ツールボックスからSubReportコントロールをドロップし、商品名グループヘッダのFormatイベントで、SubReportコントロールのReportプロパティに新しい子レポートのインスタンスを設定します。

SubReportコントロールの貼り付け
SubReportコントロールの貼り付け
商品名グループヘッダのFormatイベント設定(C#)
private void groupHeader1_Format(object sender, EventArgs e)
{
  //子レポートのインスタンスを作り、SubReportコントロールへ設定する
  SubReport1 sub1 = new SubReport1();
  this.subReport1.Report = sub1;
}
商品名グループヘッダのFormatイベント設定(VB2005)
Private Sub GroupHeader1_Format(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles GroupHeader1.Format
  '子レポートのインスタンスを作り、SubReportコントロールへ設定する
  Dim sub1 As New SubReport1()
  Me.SubReport1.Report = sub1
End Sub

 Formatイベントの記述が終わったら、商品名グループヘッダのRepeatStyleプロパティに「OnPageIncludeNoDetail」を設定し、商品名グループフッタのNewColumnプロパティには「After」を設定します。

商品名グループヘッダプロパティ
商品名グループヘッダプロパティ
商品名グループフッタプロパティ
商品名グループフッタプロパティ

テキストファイルからデータを読み込む

 これまで紹介した帳票サンプルでは、detailセクション作成時にデータソースの設定をすることで製品付属の「NWind.mdb」にアクセスしていましたが、今回は実行時にテキストファイルを直接読み取ってレポートに出力する方法を紹介します。このように、レポートに対してデータソースを指定せず、コードを記述して実行時にデータをロードする帳票を「アンバウンドレポート」と呼びます。

 今回の帳票では、親レポートで使う売上データと子レポートで使う商品名データを別々に用意しています。売上データは、「通し番号」「商品名」「売上日」「売り上げた数量」がカンマ区切りで入っている、いわゆるCSVファイルです。

売上データ(SalesData.txt)
売上データ(SalesData.txt)

 一方、子レポート側で必要なのは商品名だけなので、データはカンマ区切りのない単純なテキストファイルです。

商品名データ(ProductList.txt)
商品名データ(ProductList.txt)

 アンバウンドレポートでは、DataInitializeイベントとFetchDataイベントにデータの初期化と読み取りを記述します。また、今回はファイルからデータを読み取るため、ReportEndイベントで文字ストリームを閉じる必要があります。

 以下に各イベントで実装するコードを掲載します。便宜のため例外処理を省略していますが、実際の開発では適切な例外処理を追加してください。また、ファイル名もハードコーディングせず、パラメータとして外部から与えられるようにしておくべきでしょう。

親レポート(DailySalesList)のデータ取込処理(C#)
private StreamReader reader;

//DataInitializeイベントの処理
private void DailySalesList_DataInitialize(object sender, 
                                           System.EventArgs eArgs)
{
  // データフィールドを追加
  this.Fields.Add("SlipNo");
  this.Fields.Add("ProductName");
  this.Fields.Add("SlipDate");
  this.Fields.Add("Quantity");
  // テキストファイルをオープン
  reader
   = System.IO.File.OpenText(
        @"C:\Codezine\ActiveReports\SalesData.txt");
}
 
//FetchDataイベントの処理
private void DailySalesList_FetchData(object sender, 
        DataDynamics.ActiveReports.ActiveReport3.FetchEventArgs eArgs)
{
  //ファイルよりデータを読み込み
  string line = reader.ReadLine();
  if (line != null)
  {
      //CSVデータを配列に変換し、フィールドに取り込む
      string[] arrayValues = line.Split(",".ToCharArray());
      Fields["SlipNo"].Value = arrayValues[0];
      Fields["ProductName"].Value = arrayValues[1];
      Fields["SlipDate"].Value = arrayValues[2];
      Fields["Quantity"].Value = arrayValues[3];
      eArgs.EOF = false;
  }
  else
  {
      eArgs.EOF = true;
  }
}

//ReportEndイベントの処理
private void DailySalesList_ReportEnd(object sender, EventArgs e)
{
  reader.Close();
}
親レポート(DailySalesList)のデータ取込処理(VB2005)
Private reader As System.IO.StreamReader

'DataInitializeイベントの処理
Private Sub DailySalesList_DataInitialize(_
        ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.DataInitialize
  'データフィールドを追加
  Me.Fields.Add("SlipNo")
  Me.Fields.Add("ProductName")
  Me.Fields.Add("SlipDate")
  Me.Fields.Add("Quantity")
  'テキストファイルをオープン
  reader = System.IO.File.OpenText(_
             "C:\\Codezine\\ActiveReports\\SalesData.txt")
End Sub

'FetchDataイベントの処理
Private Sub DailySalesList_FetchData(ByVal sender As System.Object, _
      ByVal eArgs As _
        DataDynamics.ActiveReports.ActiveReport3.FetchEventArgs) _
        Handles MyBase.FetchData
  Dim line As String

  If line Is Nothing Then
        eArgs.EOF = True
  Else
      Dim arrayValues As String()
      'CSVデータを配列に変換し、フィールドに取り込む
      arrayValues = line.Split(",".ToCharArray())
      Me.Fields("SlipNo").Value = arrayValues(0)
      Me.Fields("ProductName").Value = arrayValues(1)
      Me.Fields("SlipDate").Value = arrayValues(2)
      Me.Fields("Quantity").Value = arrayValues(3)
      eArgs.EOF = False
  End If
End Sub

'ReportEndイベントの処理
Private Sub DailySalesList_ReportEnd(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.ReportEnd
  reader.Close()
End Sub

 同様に、サブレポートに対してもイベント処理コードを実装します。CSVの変換処理がないところ以外は、親レポートとほとんど同じです。

サブレポート(SubReport1)のイベント処理コード(C#)
private StreamReader reader;

//DataInitializeイベントの処理
private void SubReport1_DataInitialize(object sender, System.EventArgs eArgs)
{
  // データフィールドを追加
  this.Fields.Add("ProductName");
  // テキストファイルをオープン
  reader = System.IO.File.OpenText(
             @"C:\Codezine\ActiveReports\ProductName.txt");
}
 
//FetchDataイベントの処理
private void SubReport11_FetchData(object sender, 
      DataDynamics.ActiveReports.ActiveReport3.FetchEventArgs eArgs)
{
  // ファイルよりデータを読み込み
  string productName = reader.ReadLine();
  if (productName != null)
  {
      //読み込んだデータをフィールドに設定します。
      Fields["ProductName"].Value = productName;
      eArgs.EOF = false;
  }
  else
  {
      eArgs.EOF = true;
  }
}

//ReportEndイベントの処理
private void SubReport1_ReportEnd(object sender, EventArgs e)
{
  reader.Close();
}
サブレポート(SubReport1)のイベント処理コード(VB2005)
Private reader As System.IO.StreamReader

'DataInitializeイベントの処理
Private Sub SubReport1_DataInitialize(ByVal sender As System.Object, _
        ByVal e As System.EventArgs) Handles MyBase.DataInitialize
  'データフィールドを追加
  Me.Fields.Add("ProductName")
  'テキストファイルをオープン
  reader = System.IO.File.OpenText(_
              "C:\\Codezine\\ActiveReports\\ProductName.txt")
End Sub

'FetchDataイベントの処理
Private Sub SubReport1_FetchData(ByVal sender As System.Object, _
        ByVal eArgs As _
          DataDynamics.ActiveReports.ActiveReport3.FetchEventArgs) _
          Handles MyBase.FetchData
  Dim productName As String
  productName = reader.ReadLine()
  If productName Is Nothing Then
      eArgs.EOF = True
  Else
      Me.Fields("ProductName").Value = productName
      eArgs.EOF = False
  End If
End Sub

'ReportEndイベントの処理
Private Sub SubReport1_ReportEnd(ByVal sender As System.Object, _
      ByVal e As System.EventArgs) Handles MyBase.ReportEnd
  reader.Close()
End Sub

注意事項

 今回作成した帳票では、「商品名」行と「売上日」列で構成されるマトリックスに対して端から順番にデータを配置していくため、「売上データ、商品名データが順序保証されていること」「すべての組み合わせのデータが存在し、抜けがないこと」を前提としています。データの順序が決まっていない場合や、実際に売上のあった日のデータのみが取り込まれる場合は、必要な処理を追加していくことになります。

まとめ

 今回は改ページ制御と多段組レイアウトについて紹介しました。スクロールによって描画領域を(ほぼ無限に)広げられるWebページと異なり、「用紙サイズ」という制約のある帳票開発においては、改ページ制御1つ取ってもいろいろと細かい設定が必要になることがおわかりいただけたかと思います。

 これまで3回にわたって、帳票アプリケーション開発の基本である「表示、集計、改ページ」についてひと通り紹介しました。次回以降も、実際の帳票アプリケーション開発に役立つテクニックを紹介していきますので、お楽しみに。

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
5分でわかるActiveReports帳票連載記事一覧

もっと読む

この記事の著者

宮本奈紗(ミヤモトナサ)

株式会社システムインテグレータ ERPソリューション部所属。ERPシステムの設計・開発に従事。業務でActiveReportsを使用。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

渡辺俊史(ワタナベトシフミ)

株式会社システムインテグレータ パッケージ開発部所属。ECサイト構築パッケージの設計・開発に従事。VSUG(Visual Studio User Group) データベース・データアクセスフォーラムリーダー。blog...

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/1752 2014/02/06 11:25

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング