本稿の内容を増補改訂したアップデート版が提供されています。詳しくは連載の目次「5分でわかるActiveReports帳票」をご参照ください。
はじめに
ActiveReports for .NET(以下ActiveReports)はVisual Studioと統合された使いやすいレポートデザイナや高機能なレポートビューワ、多彩な出力形態をサポートする帳票作成コンポーネントです。
これまで紹介してきた表示、集計や改ページといった話題は、帳票アプリケーションを開発する上でどこでも必要となるものでしたが、実際の帳票開発では、データ以外にもユーザーの要求に合わせてさまざまな項目を出力する必要があります。
例えば、日本では「罫線文化」といわれるほど、きっちりと罫線の引かれた帳票が好まれるという事情があり、作成する帳票に対して細かく罫線を配置することが要求されます。今回は、ActiveReportsの罫線機能とデータ折り返しの制御、印刷・用紙設定について紹介していきます。
これまでの記事
- 第1回:5分でわかるActiveReports帳票-らくらく始める帳票作成
- 第2回:5分でわかるActiveReports帳票-集計処理と改ページ
- 第3回:5分でわかるActiveReports帳票-改ページ制御と多段組レイアウト
対象読者
- Visual Basic 2005またはVisual C# 2005を使ってプログラムを作ったことのある方。
- 帳票作成ツールに興味のある方。
必要な環境
- Visual Studio 2005、Visual Studio .NET 2003でプログラムが作れる環境。
本記事のサンプルコードはC# 2.0/Visual Basic 2005で記述しています。
罫線とデータの折り返しが含まれる帳票-「罫線」
最終的な完成イメージ
今回のサンプルはお店(飲食店)のリストです。
レイアウトは罫線で区切られており、1行に表示できる文字数が限られているため、長い文字列を表示するときは折り返して表示しなければなりません。また、データを折り返したときは行の高さも調節する必要があります。
今回は、レイアウト作成に焦点をあてた解説がメインとなるので、データは単純な構造のものを使用します。
ActiveReportsの罫線機能
ActiveReports帳票で罫線を引くには、Lineコントロールを使用します。Lineコントロールのように幅や高さの小さいコントロールをレポートデザイナに配置する場合、マウス操作だけで位置を細かく調整するのはなかなか大変です。
[レポート]メニューの[レポートの設定]-[グローバル設定]で「コントロールをグリッドにあわせる」にチェックを入れておくと、マウスやカーソルキーでコントロールを移動したときに、コントロールがグリッドに沿って移動するので、楽に配置することができます。
また、配置後に[書式]メニューの[整列]-[グリッドにあわせる]を実行しても、コントロールの位置を揃えることができます。複数のコントロールを選択して[整列]や[同じサイズに揃える]を実行すると、選択したコントロールの大きさや位置を一度に整えることができます。
また、「ActiveReports for .NET 3.0J」ツールバーには、レポートデザイナの表示を拡大・縮小する機能があります。帳票に小さなコントロールを配置するときはこちらも便利です。
なお、罫線の種類(実線、点線、破線など)や太さ、色を変更するにはそれぞれ、LineコントロールのLineStyleプロパティ、LineWidthプロパティ、LineColorプロパティを設定します。
LineコントロールのAhchorBottomプロパティを使うと、Lineコントロールの末尾を隣接するセクションまで伸ばすことができます。この機能は主に、セクションの高さが動的に変わるとき、縦線をつなぐために使います。
今回はdetailセクションに配置した縦線のLineのAnchorBottomプロパティをTrueに設定し、detailセクションの下まで縦線を伸ばすようにします。
コントロールを配置する
今回のサンプルでは明細行の高さが可変になるので、明細セクションでは下線を設定しません。後述しますが、折り返すコントロールの箇所によっては位置の自動調整が行われないため、下線とTextBoxなどのコントロールが重なってしまうことがあるためです。
ここでは、罫線の下線はグループフッタに配置します。グループが明細と同じ単位で繰り返すよう、グループヘッダのDataFieldプロパティにShopCodeを指定し、グループフッタにはDetailセクションと同じ幅のLineコントロールを配置します。
さらに、下線用グループフッタのCanShrinkプロパティをTrueにしてセクションをコントロールぎりぎりまで縮めておけば、なお良いでしょう。
罫線とデータの折り返しが含まれる帳票-「折り返し表示」
項目を折り返し表示する
TextBoxコントロールで指定した領域内で文字列を折り返して表示するには、MultiLineプロパティおよびWordWrapプロパティを使用します。また、コントロールの高さを自動的に拡張するためには、CanGrowプロパティを設定します。
プロパティ | 設定内容 |
MultiLineプロパティ | 複数の行を表示するかどうか |
WordWrapプロパティ | 複数行表示するときに、必要に応じて自動的に折り返すかどうか |
CanGrowプロパティ | 内容に合わせて、コントロールの高さを拡大するかどうか |
上段はコントロールをもともと広くとったもの、中段はコントロールを狭くしたもの、下段はCanGrowプロパティをFalseに設定し、コントロールの高さが変わらないように設定したものです。
private void detail_Format(object sender, EventArgs e) { textBox1.Text = "@@@@@MMMMM"; }
Private Sub Detail_Format( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Detail.Format TextBox1.Text = "@@@@@MMMMM" End Sub
また、途中で改行文字(\n)を入れたTextを表示させると以下のようになります。
private void detail_Format(object sender, EventArgs e) { textBox1.Text = "@@@@@\nMMMMM"; }
Private Sub Detail_Format( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Detail.Format TextBox1.Text = "@@@@@\nMMMMM" End Sub
コントロールを折り返し表示する場合は、
- CanGrowプロパティ=True
- MultiLineプロパティ=True
- WordWrapプロパティ=True
のように設定するのがベストでしょう。ActiveReportsではこの設定がデフォルト(規定値)になっています。コントロール内で文字列を折り返さない場合や、コントロールのサイズを動的に拡張しない場合は、これらのプロパティの値を必要に応じて変更するようにしてください。
折り返した際の周囲のレイアウトについて
ActiveReportsの場合、コントロールが折り返して伸びたときはBeforePrintイベントで自動的に下のコントロールの位置が調節されます。上に配置したコントロールが折り返すと、下のコントロールはすべて位置が変わります。
ただし、上と下のコントロールが重なっていた場合は、自動調整は行われません。
また、以下の縦線のように2つのコントロールを横断するコントロールがあると、自動調整は行われません。
罫線とデータの折り返しが含まれる帳票-「データ表示」
複数のデータフィールドを1つのTextBoxで表示する
お店の名前と住所の項目ですが、別々のテキストボックスに貼り付けると、先ほど説明したように、縦線コントロールが二つのコントロールをまたいでいるため、折り返した際に重なって表示されてしまいます。
そこで、二つの項目を同じTextBoxにまとめて表示させることで、重なりを回避します。1つのTextBoxコントロールに複数の値を表示させるには、DataFieldプロパティを次のように設定します。
ShopNameはテーブルの店名、ShopZipは郵便番号、ShopAdress1とShopAdress2は住所のカラム名です。先頭に「=」をつけると、ソース上の記述のようにプロパティを設定することができます。
二つの項目のフォント設定が異なる場合は、TextBoxコントロールではなく、RichTextBoxコントロールを用います。RichTextBoxコントロールはテキストの表示に複数のフォントや色を設定することのできるコントロールです。
//リッチテキストのフォント設定 Font richTextHeaderFont = new Font("MS 明朝", 12f, FontStyle.Bold); //リッチテキスト内の範囲指定をする this.richTextBoxShopNameAdress.SelectionStart = 0; this.richTextBoxShopNameAdress.SelectionLength = this.textBoxShopName.Text.Length; //選択した部分のフォントを変更する this.richTextBoxShopNameAdress.SelectionFont = richTextHeaderFont;
'リッチテキストのフォント設定 Dim richTextFont As New Font("MS 明朝", 12.0F, FontStyle.Bold) 'リッチテキスト内の範囲選択をする RichTextBox1.SelectionStart = 0 RichTextBox1.SelectionLength = Me.TextBoxShopName.Text.Length '選択したフォントを変更する RichTextBox1.SelectionFont = richTextFont
このサンプルでは、店名の長さを取得するためと背景色をつけるために、店名のみをDataFieldに設定したtextBoxShopNameというTextBoxを配置しています。
書式つき文字列にデータをバインドする
RichTextBoxコントロールでのデータバインド
RichTextコントロールでは、テキスト内にデータフィールドの値をバインドして表示させることができます。リッチテキストコントロールをダブルクリックするとテキストの編集が可能ですが、そこで
(消費税 [!TaxAmt]円)
のように記述すると、データフィールドの値をバインドすることができます。
[! ]内はFieldsのカラム名を指定します([フィールドの追加]からも指定できます)。
データソース(バウンドフィールド)の場合、はじめから値が入っていますが、自分で編集した値を組み込む場合は、前々回紹介したようにアンバウンドフィールドを作成(実行時にフィールドを追加)して使用してください。
TextBoxコントロールでのデータバインド
TextBoxコントロールのOutputFormatプロパティには、書式文字列を指定できます。
private void detail_Format(object sender, EventArgs e) { TextBoxDtilTaxAmt.OutputFormat = "\\(消費税 ###,###,##0\\円)"; }
Private Sub Detail_Format( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Detail.Format TextBoxDtilTaxAmt.OutputFormat = "\\(消費税 ###,###,##0\\円)" End Sub
この例では書式を指定する(###,###,##0)の前後にも「消費税」や「円」などの文言が含まれています。金額の範囲が0以上であることが保証されていればこの方法でよいのですが、マイナスの値が入ってくると「-(消費税 3,000 円)」のように、書式の外側にマイナス記号が表示されてしまいます。
このような場合はReportStartイベントでTextBoxコントロールのOutputFormatプロパティに書式のみを指定し、前後の文言はdetail_formatイベントで再設定することで、「(消費税 -3,000 円)」のように期待する結果を出力することができます。
private void NewActiveReport1_ReportStart(object sender, EventArgs e) { TextBoxDtilTaxAmt.OutputFormat = "###,###,##0"; } private void detail_Format(object sender, EventArgs e) { TextBoxDtilTaxAmt.Text = "(消費税 " + TextBoxDtilTaxAmt.Text + "円)"; }
Private Sub NewActiveReport1_ReportStart( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles MyBase.ReportStart TextBoxDtilTaxAmt.OutputFormat = "###,###,##0" End Sub Private Sub Detail_Format( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Detail.Format TextBoxDtilTaxAmt.Text = _ "(消費税 " + TextBoxDtilTaxAmt.Text + "円)" End Sub
ActiveReportsのプレビュー・印刷機能
レポートデザイナののプレビュー機能と用紙サイズ
第1回でも紹介しましたが、ActiveReports 3.0Jでは、Visual Studioに統合されたレポートデザイナで手軽にプレビューが行えるようになりました。レポートデザイナの左下にある「プレビュー」タブをクリックすると、帳票のプレビューが表示されます。プレビュータブに移動したとき、プロジェクトがビルドされていない場合は、自動的にビルド処理が実行されます。
プレビュー機能で表示できる最大ページ数は、Viewerコントロールと違いデフォルトでは10ページに設定されています。表示するページ数は[レポート]メニューの[レポートの設定]-[グローバル設定]で変更できます。
プレビュー機能での余白(グレーアウト部分)の表示は、[レポート]-[レポートの設定]の[ページ設定]と[プリンタ設定]にあわせて表示されます。指定された用紙の幅よりも、レポート全体の幅が大きい場合、プレビュー画面に赤い線が表示されます。
PageSettings.Margins.Left + PageSettings.Margins.Right + PrintWidth <= PageSettings.PaperWidth
レイアウトの幅はレポートエクスプローラーの一番上[レポートコンテンツ]のPrintWidthプロパティで設定します。
また、[レポート]-[レポートの設定]の[プリンタ設定]には、PCのデフォルトプリンタの印刷設定にある情報を設定できます。また、次のようなコードでプリンタごとに利用可能な用紙サイズを調べることもできます。
//usingディレクティブで「System.Diagnostics」と //「System.Drawing.Printing」を補って下さい。 NewActiveReport1 report = new NewActiveReport1(); foreach (PaperSize paper in report.Document.Printer.PaperSizes) { Debug.Write(paper.Kind.ToString() + ", "); Debug.Write(paper.PaperName.ToString() + ", "); Debug.Write(paper.Height.ToString() + ", "); Debug.WriteLine(paper.Width.ToString()); }
'Importsディレクティブで「System.Diagnostics」と '「System.Drawing.Printing」を補って下さい。 Dim report As New NewActiveReport1 For Each paper As PaperSize In report.Document.Printer.PaperSizes Debug.Write(paper.Kind.ToString() & ", ") Debug.Write(paper.PaperName.ToString() & ", ") Debug.Write(paper.Height.ToString() & ", ") Debug.WriteLine(paper.Width.ToString()) Next
なお、開発者のPCに本番環境で使うプリンタや用紙サイズを設定することができないような場合は、実行時にReportStartイベントで帳票に仮想プリンタを設定して印刷設定を変更する必要があります。仮想プリンタ設定に必要なコードはActiveReportsのコードスニペット(ActiveReports for .NET 3.0J>印刷>仮想プリンタを設定する)に含まれています。
Printメソッド実行時の印刷設定
ActiveReportsで帳票を印刷するには、DocumentプロパティのPrintメソッドを呼び出します。Printメソッドに渡すパラメータを調整することで、ユーザーが印刷内容を確認することのできるダイアログを表示させたり、帳票出力中の進行状況を表示させたりすることができます。
NewActiveReport1 report = new NewActiveReport1(); report.Run(); //Printメソッドを実行する report.Document.Print(true, false, true);
Dim report As New NewActiveReport1() report.Run() 'Printメソッドを実行する report.Document.Print(True, False, True)
Printメソッドのパラメータ指定は前から順にshowPrintDialog、showPrintProgressDialog、usePrintingThreadの値を設定します。
項目 | 内容 |
showPrintDialog | ドキュメントをプリンタに送信する前に、オプションを設定できるための印刷ダイアログを表示するかどうか |
showPrintProgressDialog | 実行中にキャンセルボタンのついた進行状況ダイアログを表示するかどうか |
usePrintingThread | 別スレッドで印刷処理を実行するかどうか |
印刷ダイアログでOKボタンが押されたかどうかを確認する
帳票アプリケーションでは、帳票出力処理を実行したあと、その印刷ジョブがプリンタに送信されたどうかを確認して処理を続行(または中止)することがあります。
ActiveReportsの標準機能ではプリンタ側に送られた印刷ジョブが成功したどうかを直接取得することはできませんが、印刷ダイアログのOKボタンが押されたかどうかはイベントの戻り値で判断することができます。
//印刷ダイアログのボタンを判定 private void printButton_Click(object sender, EventArgs e) { //帳票データ作成 NewActiveReport1 report = new NewActiveReport1(); //帳票作成 report.Run(false); //印刷ダイアログのOK=true/キャンセル=falseが戻り値 bool okButtonIsPushed = report.Document.Print(true, true, true); }
Private Sub PrintButton_Click( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles PrintButton.Click '帳票データ作成 Dim report As New NewActiveReport1 '帳票を生成 report.Run() '印刷ダイアログのOK=true/キャンセル=falseが戻り値 Dim okButtonIsPushed = report.Document.Print() End Sub
Viewerコントロールの印刷ボタンが押されたかどうかを判断したい場合は、ViewerコントロールのToolClickイベントにコードを追加します。具体的には、ToolClickEventArgsクラスのToolプロパティに含まれるID値を使用して判断します。
private void viewer1_ToolClick(object sender, DataDynamics.ActiveReports.Toolbar.ToolClickEventArgs e) { //INDEX=2のコントロール(印刷ボタン)がクリックされた if (e.Tool.Id == 2) { bool printButtonisPushed = true; } }
Private Sub Viewer1_ToolClick( _ ByVal sender As System.Object, _ ByVal e As DataDynamics.ActiveReports.Toolbar.ToolClickEventArgs) _ Handles Viewer1.ToolClick 'INDEX=2のコントロール(印刷ボタン)がクリックされた If e.Tool.Id = 2 Then Dim printButtonisPushed = True End If End Sub
WebアプリケーションでActiveReports帳票を印刷する
ActiveXビューワによる帳票の印刷・プレビュー
ActiveReportsでは、Windows Formsで利用可能なViewerコントロール同様に、Webアプリケーションにおいても、高機能なビューワを利用することができます。WebViewerコントロールを用いたアプリケーションは、Professional版でしか利用できませんが、ActiveXビューワ(arview2.cab)はStandard版でも利用できますので、今回はその使い方について紹介したいと思います。
Webアプリケーションに帳票生成ファイルを追加する
Webサイトのプロジェクト配下に直接レポートファイルを設置すると、ActiveReportsレポートデザイナのパフォーマンスが落ちてしまいます。WebアプリケーションでActiveReports帳票を開発する場合は、別途クラスライブラリのプロジェクトを作成し、それを参照した方がよいでしょう。
Webアプリケーションの実行時にはWebサイトのプロジェクト配下に直接配置しても特に問題はありません。
以下の例では、WEBアプリケーション配下のRptフォルダにレポートファイルを配置しています。
レポートレイアウトの作成方法はWindowsアプリケーションの場合と同様です。
WebページにActiveXビューワを配置する
次に、Webページでのビューワ表示部分を作成します。Webアプリケーションプロジェクトにarview2.cabを追加し、aspxファイル内では、<object>タグを使用してActiveXビューアを埋め込みます。
<object id="arv" codebase="arview2.cab#Version=2,4,2,1303"> </object>
各画面でビューワのサイズなどを指定したものを共通で利用したい場合は、ビューワ部分のHTMLソースを外部ファイル化し、インクルードするように作っておくとその後の更新が楽になります。
次に、HTMLの<head>タグの中に、データパスを指定するためのVBScriptコードを追加します。ActiveXビューワではVBScriptでプロパティを設定することで、DocumentクラスのPrintメソッドを実行するのと同様、簡単にビューワの表示・印刷ダイアログの初期値を簡単に変更できます。
<script type="text/vbscript" language="vbscript"> <!-- Sub arv_ControlLoaded() 'arv: <object>タグのid属性で指定した値 arv.DataPath = "Default.aspx?ReturnReport=1" End Sub //--> </script>
この他にも、ActiveXビューワには初期表示設定や、印刷ダイアログを表示して印刷する際の設定など、さまざまなプロパティが用意されています。
関数 | 内容 |
arv_ControlLoaded() | ビューワの読み込み |
arv_LoadedComplete() | ビューワ内のレポートの読み込み完了 |
プロパティ | 設定値 |
Printer.PaperSize | 9=A4:8=A3 |
Printer.Orientation | 1=縦:2=横 |
Printer.DeviceName | 使うプリンタデバイス |
Zoom | 初期のズーム |
Printer.RenderMode=1 | クライアント環境のOSがWindows 98/Meである場合に、文字間隔が不正になる問題を回避するためのコード |
以下のプロパティはビューワ表示ではなく、直接印刷ジョブをプリンタへ送信する場合に指定します。
プロパティ | 設定値 |
Printer.DispleyProgressDialog | True(プログレスダイアログ表示可否。直接印刷を行わない場合はFalse) |
PrintReport | True(直接印刷時のダイアログ表示可否) |
帳票を生成する
ページにActiveXビューワの表示領域を追加したら、次はビューワで表示するための帳票データの生成処理を実装します。
ASP.NET WebフォームのPage_Loadイベントに以下の処理を追加します。この処理ではActiveReports帳票を生成し、データをMemoryStreamオブジェクトに一旦格納したのちバイナリストリームとして返しています。
protected void Page_Load(object sender, EventArgs e) { MemoryStream outStream = new MemoryStream(); Rpt.NewActiveReport1 rpt = new Rpt.NewActiveReport1(); rpt.Run(false); //メモリストリームに帳票データを保存します。 rpt.Document.Save(outStream, DataDynamics.ActiveReports.Document.RdfFormat.AR20); //バッファストリームのシークポインタの位置を先頭に移動します。 outStream.Seek(0, SeekOrigin.Begin); //ストリーム読み込み用のバッファを作成し、 //ストリームのデータを読み込みます。 byte[] bytes = new byte[outStream.Length]; outStream.Read(bytes, 0, (int)outStream.Length); //出力内容をバッファ ストリームから削除します。 this.Page.Response.ClearContent(); //ヘッダへの出力内容をバッファ ストリームから削除します。 this.Page.Response.ClearHeaders(); //出力ストリームにレポートを出力します。 this.Page.Response.BinaryWrite(bytes); }
Protected Sub Page_Load(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Load Dim outStream As New MemoryStream Dim report1 As New NewActiveReport1() report1.Run(False) report1.Document.Save(outStream, _ DataDynamics.ActiveReports.Document.RdfFormat.AR20) 'バッファストリームのシークポインタの位置を先頭に移動します。 outStream.Seek(0, SeekOrigin.Begin) 'ストリーム読み込み用のバッファを作成し、 'ストリームのデータを読み込みます。 Dim bytes(outStream.Length) As Byte outStream.Read(bytes, 0, outStream.Length) '出力内容をバッファストリームから削除します。 Me.Page.Response.ClearContent() 'ヘッダへの出力内容をバッファ ストリームから削除します。 Me.Page.Response.ClearHeaders() '出力ストリームにレポートを出力します Me.Page.Response.BinaryWrite(bytes) End Sub
コードをビルドしてWeb Formを表示し、Webページにビューワと帳票が表示されれば成功です。
おわりに
今回はActiveReportsの罫線機能とデータの折り返し、プレビューと印刷機能について紹介しました。次回は、ActiveReportsで利用できるさまざまなデータソースに関する話題と、Webサービスを利用したネットワーク帳票などについて紹介する予定です。