イベントでのコードによる処理 2
イベント使用の実例
ここからは、イベントを使用した処理の例をいくつか見てみましょう。
コントロールの表示を変更する
表示されるフィールドの値をコードで加工します。
例えば、誕生日の情報から「干支」を表示する処理を以下に示します。
この時に注意すべき点としては、データソースの値を取得したい場合、フィールドを直接参照するのではなく、フィールドがバウンドされたコントロールを介して行う必要があるという点です。
以下の例では、TextBoxコントロール「txtDateOfBirth2」のDataFieldプロパティに参照したい日付型のフィールドを設定している前提です。バウンドされたコントロールのValueプロパティには元のデータの値が、Textプロパティにはフォーマットされた文字列が入っています。ValueプロパティはObject型なので、使用するときは型変換が必要です。
Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format Dim eto() As String = {"子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥"} Dim birthDay As DateTime birthDay = CType(Me.txtDateOfBirth2.Value, DateTime) Dim year As Integer = birthDay.Year Me.txtDateOfBirth2.Text = eto((year - 1900) Mod eto.Length) & "年" End Sub
private void Detail1_Format(object sender, EventArgs e) { string[] eto = { "子", "丑", "寅", "卯", "辰", "巳", "午", "未", "申", "酉", "戌", "亥" }; DateTime birthDay; birthDay = (DateTime)this.txtDateOfBirth2.Value; int year = birthDay.Year; this.txtDateOfBirth2.Text = eto[(year - 1900) % eto.Length] + "年"; }
コントロールの色を変える
フィールドの値に応じてコントロールの描画色を変えます。以下のコードでは、TextBoxコントロール「txtGender1」に性別を表す値を表示することとし、男性なら表示文字を青色、女性なら表示文字を赤色にしています。
Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format Dim gender As String gender = Me.txtGender1.Text If gender = "M" Then Me.txtGender1.Text = "男性" Me.txtGender1.ForeColor = Color.Blue End If If gender = "F" Then Me.txtGender1.Text = "女性" Me.txtGender1.ForeColor = Color.Red End If End Sub
private void Detail1_Format(object sender, EventArgs e) { string gender; gender = this.txtGender1.Text; if (gender == "M") { this.txtGender1.Text = "男性"; this.txtGender1.ForeColor = Color.Blue; } if(gender == "F"){ this.txtGender1.Text = "女性"; this.txtGender1.ForeColor = Color.Red; } }
改ページ制御をする
セクションのNewPageプロパティを制御することで、改ページを制御することができます。以下のコードでは、1ページに出力する行数(Detailセクションの数)を10行にしています。
Dim RowNumber As Integer = 0 ' 件数カウンタ Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format RowNumber += 1 If RowNumber < 10 Then ' 件数が10件に満たない場合、改ページは行いません。 Me.Detail1.NewPage = NewPage.None Else ' 10件出力した後、改ページを行い、カウンタをリセットします。 Me.Detail1.NewPage = NewPage.After RowNumber = 0 End If End Sub
private int RowNumber = 0; private void Detail1_Format(object sender, EventArgs e) { RowNumber++; if (RowNumber < 10) { // 件数が10件に満たない場合、改ページは行いません。 this.Detail1.NewPage = NewPage.None; } else { // 10件出力した後、改ページを行い、カウンタをリセットします。 this.Detail1.NewPage = NewPage.After; RowNumber = 0; } }
1行ごとに色を変える
以下のコードでは、DetailセクションのBackColorプロパティを1行ごとに変えています。
Dim ColorFlag As Boolean = False Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format If ColorFlag = True Then Me.Detail1.BackColor = Color.DarkSeaGreen Else Me.Detail1.BackColor = Color.Transparent End If Me.ColorFlag = Not Me.ColorFlag End Sub
private Boolean ColorFlag = false; private void Detail1_Format(object sender, EventArgs e) { if (this.ColorFlag) { this.Detail1.BackColor = Color.DarkSeaGreen; } else { this.Detail1.BackColor = Color.Transparent; } ColorFlag = !ColorFlag; }
ページに直接描画をする
PageクラスにはDrawText、DrawLineなどのメソッドが用意されており、コードで文字列や線などを描画することができます。
以下のコードでは、ReportEndイベントの中で、レポートを通してページ番号を描画しています。
Private Sub ProductList_ReportEnd(sender As System.Object, e As System.EventArgs) Handles MyBase.ReportEnd For i As Integer = 0 To Me.Document.Pages.Count - 1 Dim p As GrapeCity.ActiveReports.Document.Section.Page p = Me.Document.Pages(i) ' 描画する領域 Dim rect As New RectangleF(0.5, 0.5, 1, 0.2) ' 描画に必要な設定をしておく p.BackColor = Drawing.Color.Transparent p.PenStyle = GrapeCity.ActiveReports.Document.Section.PenStyles.Solid p.TextAlignment = GrapeCity.ActiveReports.Document.Section.TextAlignment.Center ' ページ数を描画する p.DrawText((i + 1) & "ページ", rect) ' 枠を描画する p.DrawRect(rect) Next End Sub
private void ProductList_ReportEnd(object sender, EventArgs e) { for (int i = 0; i < this.Document.Pages.Count; i++) { GrapeCity.ActiveReports.Document.Section.Page p; p = this.Document.Pages[i]; RectangleF rect = new RectangleF(0.5f, 0.5f, 1f, 0.2f); // 描画に必要な設定をしておく p.BackColor = Color.Transparent; p.PenStyle = GrapeCity.ActiveReports.Document.Section.PenStyles.Solid; p.TextAlignment = GrapeCity.ActiveReports.Document.Section.TextAlignment.Center; // ページ数を描画する p.DrawText((i + 1) + "ページ", rect); // 枠を描画する p.DrawRect(rect); } }
イベントではできないこと
コードにはさまざまな処理を自由に実装できるため、あらゆる制御が可能である印象も受けますが、セクションレポートのイベントによる処理にはいくつか制約があります。主な制約としては、以下のようなものがあります。
- セクションのイベント(Format、BeforePrintなど)では、そのセクション上のコントロール以外にはアクセスしてはいけません。例えば、Detailセクションのイベントからページヘッダ上のコントロールの値を変更するのはご法度です。このような実装をすると、目的とは違うページのページヘッダの値が変更される場合があります。
イベントはセクションの配置順に起動されるとは限りません。Detailセクションのイベントと、グループヘッダ/フッタのイベントや、ページヘッダ/フッタのイベントでは、順序が前後する(配置順と逆になる)場合があります。イベントの発生順に依存するような処理を実装することはおすすめできません。
- 「セクションがページのどの位置に描画されているか」を検知することは原則的にはできません。そのため、例えば「セクションがページの一番下に描画される時だけ描画内容を変更する」という動作は実現できません。
これらの注意事項について、詳しくは製品ヘルプの[よくある質問]-[セクションレポート]-[イベント]をご参照ください。