箱庭ハーブblog

7年目プログラマの趣味の小部屋

ActiveReportsでつまづきそうな所。

2012/07/26日追記
!!!!注意!!!!!!!!!!!!
Group間のFormatイベント及びBeforePrintイベントの発生順序。これらを詳細なタイミングで制御したい場合は、正確な原因を知るより実際に調べた方が早いです。傾向として言えることは、改ページ条件に関わるパラメータで前後します。SummaryをセットしたTextboxはもちろんのこと、KeepTogetherやCanGrowも影響します。データによる描画エリアの伸縮も影響してるかもしれません。


ActiveReports、Activereports、activereports、Active Reports、active reports、グループ、マルチカラム、アンバウンド


ご無沙汰です。10月頭に引っ越した影響もあり、色々忙しい毎日で記事を書く暇がない!!!といった感じになっていましたが、ようやく余裕が出てきました。今回はここ最近延々とActiveReportsで帳票を作っていたので、それに関するTipsでも。

ActiveReportsは帳票を作成するのに特化した有料のVisualstudio拡張ツールです。簡単な帳票のデザインならば、一切コードを書くことなく帳票用のクラスを作ることが出来るのが特徴でしょう。基本的にはデータベースなどから引っ張ってきた情報をインスタンス化したレポートに流し込んでやることで、勝手にレポートが出来る優れもので、以下のようなレポートが作れます。
  1. レコードを出力するレポート
  2. 固定行数レポート
  3. グループ化を活用したレポート
  4. マルチカラムなレポート(DownAcross。左上から下に進み、右隣の上へ続く。)
  5. マルチカラムなレポート(AcrossDown。左上から右に進み、下隣の左へ続く。)
  6. 全てプログラムで制御するレポート
非常に優れたツールなのですが、実際の詳細挙動はどうなっているんだろうと考えた時に「?」となることが多いのも特徴です。そんなツールなので、実際にどういった挙動になっているのか少し突っ込んでみましょう。

まずは大原則から。これだけは最低押さえておきましょう。
・Detailセクションは、渡されたDataTableのレコード数の数だけ繰り返す。
・DataFieldを設定すると、渡されたDataTableの列に同名のものがあればその値が入る。
・GroupHeaderのDataFieldを設定すると、実際に入った値が違うたびに別グループになる
・セクションの全ての値が暫定的に確定するまで、セクション_Formatは呼ばれない。


詳細なレポート生成手順を俯瞰します。
  • ReportStartイベント。(※1)
  • DataInitializeイベント。
  • for{
        FetchDataイベント。イベントハンドラ終了後、レコードが読み込まれる。
        if (セクションの内容が全て確定(※2)){
            セクション_Formatイベント。ハンドラ終了後、セクションの高さが確定する。(※3)(※4)
            セクション_BeforePrintイベント。イベントハンドラ終了後、描画。
          セクション_AfterPrintイベント

        }
    }
  • ReportEndイベント。
(※1)コントロールを動的に追加する場合、ここでのみ可能。
(※2)Detail_Formatはレコードごとに発生する。
(※3)Detail_Format終了後、グループの判定(GroupValueが前回と等しいかどうか)が行われる。
(※4)GroupFooter_Formatが開始されるタイミングは、複雑。

なかなかに極まってます。
覚えておくといいのは、Groupフッターを描画するかの判定が、いつ判定されるかでしょう。次のグループの先頭レコードに相当するDetail_Format終了後に判定されます。場合によってはこの後に、GroupFooter_Formatが呼ばれる前に、前の行のDetail_BeforePrintが呼ばれたり、次のグループのDetailのBeforePrintが呼ばれたりするので注意が必要です。
また、GroupFooterにいるsummaryが設定されたコントロールは、GroupFooterのFormatの時点では算出されていないケースがあるので注意です。



もう1つわかりにくいものに、多段組みでAcrossDownを採用した時の挙動があります。
結論から言うと、次のように挙動します。 
  • Groupヘッダやフッタは、セクションごとに1列分確保され、Detailの横に付く。
  • UnderLayout=TrueかVisibleをFalseにすれば、列幅は確保されない。
  • 列幅を超えた分は、描画されない。
  • GroupのNextColumnは、改行として機能する。
  • GroupのColumnLayoutをFalseにすると、通常通りの挙動なる。また、NextColumnは意味を持たなくなる。
なかなか便利ですが、グループヘッダだろうがフッタだろうが、1列分しかスペースは確保できない気がします。自由に調整する方法を知っていたら、誰か教えてください。なお多段組を上手く活用すれば、元データによっては上手く表にすることもできたりするのでなかなか奥が深いです。



最後に、サブレポート。
サブレポートで注意しておきたいのは、サブレポートをPageHeaderやFooterに入れるのはあまり推奨しません。高さが変わりません。サブレポート自体はデータソースをが複数必要になる帳票で非常に重宝しますが、外枠線などに微妙な感じがそこはかとなく。デザインをころうとするとちょっと嫌な挙動をしたりすることもあります。

ActiveReportsは非常に優秀なツールです!値段もかなり高い部類に入るツールかもしれませんが、会社で使うことがあるならありがたく使っていきましょう!

  






2013/02/28 追記
ReportStartとDataInitializeの違い

ReportStartはReport生成処理が行われる前に呼ばれます。
そのため、自由にコントロールを追加できます。
コントロールを動的に生成して追加するには以下のようにします。
セクションインスタンス.Controls.Add(hoge)

DataInitializeは、ReportStart後の初期化処理後、最初のFetchDataが呼ばれる前に呼ばれます。
この段階でDataSource(=DataTable)の列名は、Fieldsにコピーされています。
DataSourceにない列(つまりDetaField)を追加したい場合、このタイミングで可能です。
レポートインスタンス.Fields.Add(hoge)
コメント
PAGETOPへ

コメント送信

お名前
タイトル
文字色
メールアドレス
URL
コメント
パスワード

パスワードを入れておかないと、コメントの再編集ができません!

フリーエリア

takemori
Twitter : @takemori_kondo

1. Unityと戯れてます
2. Cake3は劣化じゃないRails

iOS
coming soon...

Windows
Html Editor - Nazuna
Managed DirectX サンプル集

beginning since
2006.08.17
renewaled on
2011.06.03

最新コメント

[2013/06/14 ミューネ]
[2012/08/30 ノートPC]