画面と帳票のイメージが近い業務アプリケーションを作成
業務アプリケーションの作成では、画面で入力した内容をそのまま帳票で印刷するなど、画面と帳票が密接に結びついている場合が多々あります。このようなケースに多い要望が、帳票と同じイメージの画面レイアウトです。
そこで今回は、MultiRow for Windows Forms 6.0J、InputMan for Windows Forms 6.0J、ActiveReports for .NET 6.0Jを組み合わせて、業務で現在使用している請求明細書をシステム化するというシナリオで、画面と帳票のイメージが近い業務アプリケーションを作成してみたいと思います。
なお、今回のサンプルソースには、下記の3つのサンプルが含まれています。
- CZ0905Bound
- CZ0912Bound
- CZ0912MultiRow
帳票を作成する
画面と帳票のどちらを先に作成するかはケースバイケースなのですが、画面よりも帳票の方が最終成果物としてのコダワリのあるクライアントが多く、そのようなクライアントの場合は帳票デザインから先に固めてしまうのがよいでしょう。今回も、帳票デザインを最初に確定するためにActiveReports for .NET 6.0Jで帳票を作成することになったと想定して進めていきます。
ActiveReports for .NET 6.0Jの新機能でより紙に近いデザインを実現する
以前紹介した3.0Jも帳票印刷に必要なさまざまな機能を備えていましたが、最新バージョンである6.0Jでは、さらにその機能が洗練され使いやすくなっています。
例えば、明細行が1ページあたり30行のデザインを作成した場合に4行しかデータがないと、図1左のように外側の枠線も4行分で終わってしまいますが、6.0Jでは図1右のように外側の枠線は常に30行分の大きさで引くといったことが可能です(サンプル「CZ0912Bound」)。
6.0Jではこのような枠線を引くために、CrossSectionBoxとCrossSectionLineという2つのコントロールが追加されています。このコントロールを使うことで、ページヘッダからページフッタまでをまたがって罫線が引けるため、明細行の実データ行数に左右されない印字が可能になっています。
参照設定を行う
新規にWindowsアプリケーションのプロジェクトを作成してActiveReports for .NET 6.0Jを使用する場合には、プロジェクトに参照設定を追加します。また、ActiveReports for .NET 3.0Jで作成したプロジェクトを6.0Jで流用するためには3.0Jと6.0Jでは名前空間(「DataDynamics.ActiveReports.ActiveReport3」→「DataDynamics.ActiveReports.ActiveReport」)などが異なるため参照設定をやりなおす必要があります。参照設定は次の手順で行います。
- Visual Studioでプロジェクトを開いたら、ソリューションエクスプローラで[参照の追加]をクリックして「参照の追加ダイアログボックス」を表示します。
- ダイアログボックスでActiveReports for .NET 6.0Jを使うときの必須コンポーネントである「GrapeCity ActiveReports Document」「GrapeCity ActiveReports for .NET」および「GrapeCity ActiveReports Viewer」を選択して[OK]ボタンをクリックします。
帳票をデザインしていると罫線と他のコントロールが重なることが多く、ActiveReportsでも下側のコントロールが選択しづらいときがよくあります。このような時は、[表示]-[その他のウィンドウ]-[ActiveReports 6.0Jレポートエクスプローラ]メニューをクリックしてレポートエクスプローラを起動すれば、ツリー表示から目的のコントロールを素早く確実に選択できます。
データ取得と印刷のコーディング
サンプル「CZ0912Bound」は、以前の記事でのサンプル「CZ0905Bound」に対して参照設定と名前空間の変更を行い、帳票定義体もCrossSectionBoxコントロールとCrossSectionLineコントロールに変更したサンプルになります。コードの詳しい説明は前回の記事と重複するため割愛しますが、データセットをActiveReportsで印刷するにはリスト1のようなコードを記述します。
Public Class CZ0912Bound_Form Private Sub Me_Shown(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Shown Dim rpt As New Seikyu_Report() Application.DoEvents() Using _prco As New CZ0912Bound rpt.DataSource = _prco.GetRecords("admin", "").Tables(0) Viewer1.Document = rpt.Document rpt.Run() End Using End Sub End Class
画面を作成する
期待する帳票が出力できたら、次は画面の作成にとりかかります。ここで非常に役に立つのが、MultiRow for Windows Forms 6.0Jの新機能の1つである「トレーシングモード」です。
あらかじめ請求明細書を画像ファイルとして保存しておけば、図5のようにトレーシングモードでMultiRowのテンプレートデザイナの背景として表示できます。画像は表示倍率も変えられ、表示位置もセクションごとに別々に変えられるので、例えば図5でも、ヘッダセクションに含まれる要素を少なくして帳票には必要でも入力画面では不要な部分を除いた位置に表示することもできます。
このように表示した帳票の現物の上にMultiRowのセルコントロールを配置していけば直感的に同じデザインが作成できます。
MultiRow 6.0Jの新機能:InputManコントロールを使用する
MultiRowのセルはWindowsフォームの標準コントロールを使用しています。そのため、業務アプリケーションを作成していると標準コントロールの機能ではなくInputManの機能が使いたくなる時があります。もし、MultiRow for Windows Forms 6.0JとInputMan for Windows Forms 6.0Jの両方を使用しているならば、グレープシティのWebサイトから「InputManCell for Windows Forms 6.0J」をダウンロードして追加インストールすることで、MultiRowのセルとしてInputManコントロールが使用できるようになります。
MultiRow 6.0Jの新機能:セルコントロールの置換
MultiRow for Windows Forms 6.0Jは、このままでも配置済のセルコントロールを別の型のセルコントロールに簡単に変更できます。テンプレートデザイナで該当のセルコントロールを右クリックし、[置換]メニューから置換先のセルコントロールを選択すれば、可能な限りプロパティなどを転記して新しいセルコントロールに変更されます。もちろん、InputManCellが使えるならばInputManCellに置換することも可能です。
計算列の指定
各明細行やヘッダやフッタにサマリー型セルコントロールを配置して、Calculationプロパティを設定しておけば自動計算が可能です。
例1:明細行の合計を求める
明細部分の「Price_Cell」セルの合計をヘッダセクションに表示したいときは、ヘッダセクションにサマリー型セルコントロールを配置して次のようにプロパティを設定します。
Calculation | MathStatistics |
CellName | Price_Cell |
ExcludeHiddenRows | True |
Statistics | Sum |
例2:消費税を計算する
税抜き合計価格を表示した「NowConsume_Cell」セルから消費税を自動計算したいときは、サマリー型セルコントロールに次のようにプロパティを設定します。
Calculation | Expression |
Expression | NowConsume_Cell * 0.05 |
Windowsフォームに配置する
テンプレートが作成できたらWindowsフォームに配置したMultiRowコントロールのTemplateプロパティに指定します。図8では赤線で囲まれた部分がMultiRow部分になります。
データ連携コードを記述する
データセットの内容を表示する
.NETでは、さまざまなコントロールが項目名を指定しておいてデータソースにDataTableを指定すると、指定した項目名と一致する列の値を自動的に画面に表示できます。MultiRowでも明細行に相当するRowセクションに配置したセルコントロールのDataFieldプロパティに項目名を指定しておけば、DataTableに含まれているレコードを自動的にすべて表示することが可能です。
Using _prco As New CZ0912Bound ds = _prco.GetRecords("admin", "", billNo) End Using Me.GcMultiRow1.DataSource = ds Me.GcMultiRow1.DataMember = "Bill"
ヘッダセクションやフッタセクションについてはDataFieldプロパティを指定しても自動的に表示されないので、Cellsプロパティでセル名を明示的に指定したコードを記述しなければなりません。
Me.GcMultiRow1.ColumnHeaders(0).Cells("CustomerName_Cell").Value = _ ds.Tables("Bill").Rows(0).Item("CustomerID") With ds.Tables("BillCondition").Rows(0) Me.GcMultiRow1.ColumnHeaders(0).Cells("EndDate_Cell").Value = .Item("EndDate") Me.GcMultiRow1.ColumnHeaders(0).Cells("PreInvoice_Cell").Value = .Item("PreInvoice") Me.GcMultiRow1.ColumnHeaders(0).Cells("PreIncome_Cell").Value = .Item("PreIncome") End With
データセットを更新する
画面の内容をDataSetに反映する場合も、表示するときと同様に明細部分については自動的に画面の内容がDataTableに反映されますが、ヘッダセクションやフッタセクションに配置したセルコントロールの内容は、Cellsプロパティにセル名を指定して明示的に値を転記しなければなりません。
With ds.Tables("BillCondition").Rows(0) .BeginEdit() .Item("PreInvoice") = Me.GcMultiRow1.ColumnHeaders(0).Cells("PreInvoice_Cell").Value .Item("PreIncome") = Me.GcMultiRow1.ColumnHeaders(0).Cells("PreIncome_Cell").Value .Item("CarryOver") = Me.GcMultiRow1.ColumnHeaders(0).Cells("CarryOver_Cell").Value .Item("NowConsume") = Me.GcMultiRow1.ColumnHeaders(0).Cells("NowConsume_Cell").Value .Item("NowTax") = Me.GcMultiRow1.ColumnHeaders(0).Cells("NowTax_Cell").Value .Item("NowInvoice") = Me.GcMultiRow1.ColumnHeaders(0).Cells("NowInvoice_Cell").Value .Item("EndDate") = Me.GcMultiRow1.ColumnHeaders(0).Cells("EndDate_Cell").Value .EndEdit() End With Using _prco As New CZ0912Bound If _prco.SetRecords(ds, "admin", "", billno) Then Me.Update_Button.Enabled = False Me.Print_Button.Enabled = True Me.ToolStripStatusLabel1.Text = Now.ToString("MM/dd hh:mm:ss") End If End Using
実行結果
サンプル「CZ0912_MultiRow」を実行して右上の請求番号を選択して[検索]をクリックすれば、該当する請求明細書のデータをmdbファイルから読みだして画面に表示します。画面上で値を変更したときは自動計算項目については、自動計算が行われ、変更値に連携した値になります。
[更新]をクリックすれば画面上の値でmdbファイルの内容を変更します。なお、Visual Studio上で実行した場合は、「bin\debug」フォルダなどにコピーされたmdbファイルが更新されるので、実行するたびに初期値の内容になります。注意してください。
印刷機能を追加する
ActiveReportsで作成した帳票デザインとプレビュー表示フォームの2つを、サンプル「CZ0912MultiRow」に追加します。
CZ0912_Form.vbで表示中のデータを印刷したいので、プレビュー表示フォーム(CZ0912Bound_Form.vb)のShowDialogメソッドに請求番号を渡すためのパラメータを追加して、リスト5のようなコードにします。
Public Class CZ0912Bound_Form Private _billNo As String = String.Empty Public Shadows Function ShowDialog(ByVal owner As Form, _ ByVal billNo As String) As DialogResult _billNo = billNo Return MyBase.ShowDialog(owner) End Function Private Sub Me_Shown(ByVal sender As Object, _ ByVal e As System.EventArgs) Handles Me.Shown Dim rpt As New Seikyu_Report() Application.DoEvents() Using _prco As New CZ0912Bound rpt.DataSource = _prco.GetPrintRecords("admin", "", _billNo).Tables(0) Viewer1.Document = rpt.Document rpt.Run() End Using End Sub End Class
この画面を呼び出すためのコードは、CZ0912_Form.vbに[印刷]ボタンを追加して、ボタンをクリックしたらプレビュー表示フォームを呼び出すようにします。
Private Sub Print_Button_Click(ByVal sender As System.Object, _ ByVal e As System.EventArgs) Handles Print_Button.Click Me.Cursor = Cursors.WaitCursor Me.ToolStripStatusLabel1.Text = "印刷中" Me.Refresh() Try Using _form As New CZ0912Bound_Form _form.Showdialog(Me,Me.GcMultiRow1.ColumnHeaders(0).Cells("BillNo_Cell").Value.ToString) End Using Me.ToolStripStatusLabel1.Text = Now.ToString("MM/dd hh:mm:ss") Catch ex As Exception Me.ToolStripStatusLabel1.Text = ex.Message Finally Me.Cursor = Cursors.Default End Try End Sub
まとめ
サンプル「CZ0912MultiRow」では、事前に作成した帳票出力コードを最大限利用するために印刷時に再度mdbファイルから値を取得しています。もちろん、印刷時にはmdbファイルから取得せずに画面に表示中のDataSetを渡して印刷するようにも変更可能なので、ぜひチャンレジしてみてください。