thongkorn โพสต์ 2017-11-10 13:28:28

[VB.NET] พื้นฐานการพิมพ์รายงานด้วย ActiveReports .NET ลงบนกระดาษขนาด A4

http://www.g2gnet.com/webboard/images/vbnet/ARNetSimple.png
การทำรายงาน หรือ Report แบบ Hard Copy ก็จะมีอยู่ 2 ค่ายหลักใหญ่ๆคือ Crystal Report หรือ CR และ ActiveReports หรือ (AR) สำหรับตัวแอดมินเองถนัดและชื่นชอบการใช้งาน AR มาตั้งแต่ยุค AR2 ActiveX/COM ซึ่งเดิมเป็นของค่าย DataDynamics แต่ตอนหลังก็ถูกรวบไปขึ้นอยู่กับเมืององุ่น GrapeCity สาเหตุที่แอดมินชอบเจ้า AR เป็นพิเศษ ก็เพราะว่าลักษณะการทำงานของ AR จะเหมือนกับฟอร์มๆหนึ่งในตัว Visual Basic เอง และตัวมันเองสามารถทำการแสดงผลข้อมูลได้ดีและรวดเร็วทั้ง Bound Data และ UnBound Data ... จบ ...
อ่านรายละเอียดเพิ่มเติมกับแหล่งข้อมูลของ ActiveReports รุ่นต่างๆได้ที่นี่ ...
หรือ
ดาวน์โหลดชุดติดตั้ง ActiveReports .NET (V6) ได้ที่นี่ (เฉพาะสมาชิกเท่านั้น)
อ่านวิธีการเรียกใช้งาน ActiveReports แบบเบื้องต้น
ก้าวแรกกับการพิมพ์รายงานด้วย ActiveReports .NET
ขอสรุปการทำงานของ AR ให้ฟังแบบสั้นๆก็คือ ... ทุกๆครั้งที่เรียกใช้งาน ActiveReports จะเริ่มกระบวนการขั้นตอนแรกที่โปรแกรมย่อยที่มีชื่อว่า ReportStart เพื่อทำการตั้งค่าหน้ากระดาษ ค่าตัวแปร หรือ Control ต่างๆในแบบ @Run Time เพียงครั้งแรกครั้งเดียวก่อนที่จะทำการพิมพ์ แต่หลังจากนั้น ...

หลักการที่สำคัญของ ActiveReports
(1) เริ่มการอ่านแถวข้อมูลเข้ามาจากโปรแกรมย่อย FetchData โดยทำการเปรียบเทียบค่าด้วยการนับรายการ (หากใช้ฐานข้อมูลจริง ส่วนนี้ก็จะใช้ในการทำกรุ๊ปด้วย)
(2) หากข้อมูลหรือจำนวนแถวยังไม่หมด นั่นคือ EOF (หรือ End Of File) = False ก็กระโดดมาทำการพิมพ์ที่Detail1_Format หากหมดข้อมูลแล้ว EOF = True ก็จะสิ้นสุดกระบวนการพิมพ์
(3) กลับไปข้อที่ 1 อีกครั้ง เพื่อตรวจสอบว่ามีข้อมูลจะพิมพ์อีกหรือไม่
*** ขั้นตอนทั้งหมดนี้ คุณจะมองเห็นภาพได้อย่างชัดเจนก็ต่อเมื่อคุณใช้ Debugger ***
http://www.g2gnet.com/webboard/images/vbnet/ARNetReference.png
References ... ก่อนการใช้งานต้องเรียกเข้ามาก่อนเสมอนะครับ

มาดูโค้ดในส่วนของ ActiveReports ...
    ' / --------------------------------------------------------------------------------
    ' / ทุกๆครั้งที่เริ่มต้นสั่งพิมพ์ จะต้องตั้งค่าเริ่มต้นใน ReportStart เพียงครั้งแรกและครั้งเดียว
    Private Sub AR6PrintEmployee_ReportStart(sender As Object, e As System.EventArgs) Handles Me.ReportStart
      '/ การตั้งค่าหน้ากระดาษ
      With PageSettings
            '/ หน่วยวัดเป็นนิ้ว (ใช้ CmToInch ด้วยการรับค่าเซนติเมตร แต่แปลงเป็นนิ้วแทน เพื่อวัดระยะได้ง่ายกว่า)
            .Margins.Left = CmToInch(1.5)
            .Margins.Right = CmToInch(0.2)
            .Margins.Top = CmToInch(1.5)
            .Margins.Bottom = CmToInch(1.5)
            ' ตั้งค่ากระดาษแนวตั้ง
            .Orientation = PageOrientation.Portrait
            ' กระดาษขนาด A4
            .PaperKind = Drawing.Printing.PaperKind.A4
            ' กรณีที่กำหนดขนาดกระดาษเอง
            ' .PaperKind = Drawing.Printing.PaperKind.Custom
      End With
      ' ปกติต้องเคลียร์ค่าต่างๆของ TextBox ก่อนการพิมพ์
      txtEmployeeID.Text = ""
      txtEmployeeName.Text = ""
      txtPosition.Text = ""
      txtDepartment.Text = ""
      txtSalary.Text = ""
    End SubReportStart ...

ส่วนของการอ่านข้อมูลเข้ามา (Fetch Data) แล้วตรวจสอบว่าพิมพ์หมดหรือยัง ...
    ' / --------------------------------------------------------------------------------
    ' / เมื่อพิมพ์ข้อมูลจาก Detail1_Format เสร็จก็จะวนกลับมาเรียกข้อมูล (Fetch Data) ใหม่อีกครั้ง
    ' / ด้วยการเลื่อนค่าจำนวนแถวขึ้น ItemNo +1 แล้วเทียบกับจำนวนแถวใน DataGrid
    Private Sub AR6PrintEmployee_FetchData(sender As Object, eArgs As DataDynamics.ActiveReports.ActiveReport.FetchEventArgs) Handles Me.FetchData
      ItemNo = ItemNo + 1
      '/ ตรวจสอบจำนวนการพิมพ์ทั้งหมด ด้วยการนับจำนวนแถวใน DataGrid ที่อยู่ในฟอร์มหลัก
      '/ จะส่งค่าจำนวนแถวมาก็ได้ แต่ผมเลือกอ้างถึงตัว DataGrid ใน frmARNetSimple โดยตรง
      If ItemNo > frmARNetSimple.DataGridView1.RowCount Then
            '// หากหมดแล้วก็จบการพิมพ์
            eArgs.EOF = True
            '// ยังไม่หมดข้อมูล
      Else
            eArgs.EOF = False
      End If
    End Sub
โค้ดในส่วนของการพิมพ์รายละเอียดข้อมูล (Detail) ...
    ' / --------------------------------------------------------------------------------
    ' / รายละเอียดต่างๆก็จะนำมาแสดงใน Detail
    Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format
      '/ การอ้างถึงค่าในแต่ละแถว, หลักของ DataGridView Control ที่อยู่ใน frmARNetSimple
      '/ ค่า ItemNo เริ่มต้นจาก 1 แต่ลำดับแถวใน DataGrid จะเริ่มต้นจาก 0 (Index=0) ก็เลยต้องลบออกด้วย 1
      txtEmployeeID.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(0).Value
      '/ แถว 0 หลัก 1
      txtEmployeeName.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(1).Value
      '/ แถว 0 หลัก 2
      txtPosition.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(2).Value
      '/ แถว 0 หลัก 3
      txtDepartment.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(3).Value
      '/ แถว 0 หลัก 4 (CDbl = Convert To Double)
      txtSalary.Text = Format(CDbl(frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(4).Value), "#,##0.00")
      '/ จากนั้นก็เริ่มแถวใหม่(แต่หลักคงเดิม)

      '/ หาเลขคู่กับเลขคี่ เพื่อพิมพ์ลาเบล lblBG สลับสีในการพิมพ์แต่ละแถว
      '/ หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 0 = เลขคู่
      If (ItemNo Mod 2) = 0 Then
            lblBG.BackColor = Color.Cornsilk
            '/ หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 1 = เลขคี่
      Else
            lblBG.BackColor = Color.Azure
      End If

      '/ จากนี้มันก็กระโดดกลับไปที่ Sub FetchData เพื่ออ่านค่าเข้ามาพิมพ์ใหม่
      '/ หากหมดจำนวนแถวที่ต้องการพิมพ์ (นับจำนวนแถวใน DataGrid) ก็จะจบการทำงาน (EOF=True)
    End Sub
โค้ดในส่วนของการกำหนด ActiveReports Designer เข้ากับไฟล์รายงาน ... ซึ่งจะอยู่ในฟอร์มหลักที่เรียกใช้งาน (frmARNetSimple.vb)
    ' / --------------------------------------------------------------------------------
    ' / Print Preview ก่อนทำการพิมพ์
    Private Sub btnPreview_Click(sender As System.Object, e As System.EventArgs) Handles btnPreview.Click
      Dim rpt As New ARNetSimple
      ' / --------------------------------------------------------------------------------
      ' / ส่วนที่สำคัญในการผูก ARDesigner เข้ากับรายงาน
      ' / Instance name ARDesigner มันจะชี้ไปที่ไฟล์ ARNetSimple.vb
      ' / โหลดรายงาน Document (ARNetSimple) เข้าสู่ ActiveReports Viewer
      Me.Viewer1.Document = rpt.Document
      ' / --------------------------------------------------------------------------------
      ' / ปรับการย่อขยาย (Zoom) ของหน้ารายงาน
      Viewer1.ReportViewer.Zoom = 0.85 ' 85%
      ' / Run Report
      rpt.Run()
    End Sub
มาดูโค้ดฉบับเต็มในฟอร์มหลักของ VB.NET ...
Public Class frmARNetSimple

    Private Sub frmARNetSimple_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      Me.Dispose()
      Application.Exit()
    End Sub

    Private Sub frmARNetSimple_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      Call InitGrid()
      Call FillDataSample()
    End Sub

    '// Sample Data
    Private Sub FillDataSample()
      Dim row As String() = New String() {"EMP00001", "นายทองก้อน ทับทิมกรอบ", "Managing Director", "Management", "1,999,999"}
      DataGridView1.Rows.Add(row)
      row = New String() {"EMP00002", "นายบุญห่อ พ่อรวย", "ช่างเขาเถอะ", "Technical", "8,500"}
      DataGridView1.Rows.Add(row)
      row = New String() {"EMP00003", "นางสาวกุ๊กกิ๊ก น่ารักที่สุด", "เลขา", "Management", "27,500.75"}
      DataGridView1.Rows.Add(row)
      row = New String() {"EMP00004", "นางบัวผัน ฝันเฟื่อง", "หัวหน้าบัญชี", "บัญชี", "200"}
      DataGridView1.Rows.Add(row)
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / การกำหนดค่าต่างๆให้กับตารางกริดแบบ @Run Time
    Private Sub InitGrid()
      Dim Column0 As New DataGridViewTextBoxColumn()
      Dim Column1 As New DataGridViewTextBoxColumn()
      Dim Column2 As New DataGridViewTextBoxColumn()
      Dim Column3 As New DataGridViewTextBoxColumn()
      Dim Column4 As New DataGridViewTextBoxColumn()
      With DataGridView1
            With Column0
                .Name = "EmployeeID"
                .HeaderText = "รหัสพนักงาน"
                .HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
            End With
            With Column1
                .Name = "Fullname"
                .HeaderText = "ชื่อ - นามสกุล"
                .HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleLeft
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleLeft
            End With
            With Column2
                .Name = "PositionName"
                .HeaderText = "ตำแหน่ง"
            End With
            With Column3
                .Name = "DepartmentName"
                .HeaderText = "แผนก"
            End With
            With Column4
                .ValueType = GetType(Double)
                .Name = "Salary"
                .HeaderText = "เงินเดือน"
                '// Value type
                .ValueType = GetType(System.Decimal)
                '// Format number 2 decimal place.
                .DefaultCellStyle.Format = "N2"
                .HeaderCell.Style.Alignment = DataGridViewContentAlignment.MiddleRight
                .DefaultCellStyle.Alignment = DataGridViewContentAlignment.MiddleRight
            End With
            With DataGridView1
                .Columns.Add(Column0)
                .Columns.Add(Column1)
                .Columns.Add(Column2)
                .Columns.Add(Column3)
                .Columns.Add(Column4)
            End With
            '// Sample coding with Run-Time
            With DataGridView1
                .RowHeadersVisible = True
                .AllowUserToAddRows = False
                .AllowUserToDeleteRows = False
                .AllowUserToResizeColumns = False
                .AllowUserToResizeRows = False
                .SelectionMode = DataGridViewSelectionMode.FullRowSelect
                .MultiSelect = False
                .ReadOnly = True
                '// Data rows
                .Font = New Font("Tahoma", 9)
                .RowTemplate.MinimumHeight = 20
                .RowTemplate.Height = 26
                '// Column Header
                .ColumnHeadersHeight = 30
                .ColumnHeadersHeightSizeMode = DataGridViewColumnHeadersHeightSizeMode.EnableResizing
                '// แสดงสีสลับแถวคู่-คี่
                .AlternatingRowsDefaultCellStyle.BackColor = Color.AliceBlue
                '// ปรับขนาดความกว้างของหลักให้พอดี
                .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
                .AutoResizeColumns()
                '// Header Own Style
                With .ColumnHeadersDefaultCellStyle
                  .BackColor = Color.Navy
                  .ForeColor = Color.Black
                  .Font = New Font("Tahoma", 9, FontStyle.Bold)
                End With
            End With
      End With
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / Print Preview ก่อนทำการพิมพ์
    Private Sub btnPreview_Click(sender As System.Object, e As System.EventArgs) Handles btnPreview.Click
      Dim rpt As New ARNetSimple
      ' / --------------------------------------------------------------------------------
      ' / ส่วนที่สำคัญในการผูก ARDesigner เข้ากับรายงาน
      ' / Instance name ARDesigner มันจะชี้ไปที่ไฟล์ ARNetSimple.vb
      ' / โหลดรายงาน Document (ARNetSimple) เข้าสู่ ActiveReports Viewer
      Me.Viewer1.Document = rpt.Document
      ' / --------------------------------------------------------------------------------
      ' / ปรับการย่อขยาย (Zoom) ของหน้ารายงาน
      Viewer1.ReportViewer.Zoom = 0.85 ' 85%
      ' / Run Report
      rpt.Run()
    End Sub
End Class
โค้ดฉบับเต็มในส่วนของ ActiveReports ...
Imports DataDynamics.ActiveReports
Imports DataDynamics.ActiveReports.Document

Public Class ARNetSimple
    ' ตัวแปรนี้ต้องประกาศเป็นแบบ Public เพื่อให้ส่วนของ Detail1_Format และ FetchData มองเห็นด้วย
    Private ItemNo As Integer

    ' / --------------------------------------------------------------------------------
    ' / เมื่อพิมพ์ข้อมูลจาก Detail1_Format เสร็จก็จะวนกลับมาเรียกข้อมูล (Fetch Data) ใหม่อีกครั้ง
    ' / ด้วยการเลื่อนค่าจำนวนแถวขึ้น ItemNo +1 แล้วเทียบกับจำนวนแถวใน DataGrid
    Private Sub AR6PrintEmployee_FetchData(sender As Object, eArgs As DataDynamics.ActiveReports.ActiveReport.FetchEventArgs) Handles Me.FetchData
      ItemNo = ItemNo + 1
      '/ ตรวจสอบจำนวนการพิมพ์ทั้งหมด ด้วยการนับจำนวนแถวใน DataGrid ที่อยู่ในฟอร์มหลัก
      '/ จะส่งค่าจำนวนแถวมาก็ได้ แต่ผมเลือกอ้างถึงตัว DataGrid ใน frmARNetSimple โดยตรง
      If ItemNo > frmARNetSimple.DataGridView1.RowCount Then
            '// หากหมดแล้วก็จบการพิมพ์
            eArgs.EOF = True
            '// ยังไม่หมดข้อมูล
      Else
            eArgs.EOF = False
      End If
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / รายละเอียดต่างๆก็จะนำมาแสดงใน Detail
    Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format
      '/ การอ้างถึงค่าในแต่ละแถว, หลักของ DataGridView Control ที่อยู่ใน frmARNetSimple
      '/ ค่า ItemNo เริ่มต้นจาก 1 แต่ลำดับแถวใน DataGrid จะเริ่มต้นจาก 0 (Index=0) ก็เลยต้องลบออกด้วย 1
      txtEmployeeID.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(0).Value
      '/ แถว 0 หลัก 1
      txtEmployeeName.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(1).Value
      '/ แถว 0 หลัก 2
      txtPosition.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(2).Value
      '/ แถว 0 หลัก 3
      txtDepartment.Text = frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(3).Value
      '/ แถว 0 หลัก 4 (CDbl = Convert To Double)
      txtSalary.Text = Format(CDbl(frmARNetSimple.DataGridView1.Rows(ItemNo - 1).Cells(4).Value), "#,##0.00")
      '/ จากนั้นก็เริ่มแถวใหม่(แต่หลักคงเดิม)

      '/ หาเลขคู่กับเลขคี่ เพื่อพิมพ์ลาเบล lblBG สลับสีในการพิมพ์แต่ละแถว
      '/ หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 0 = เลขคู่
      If (ItemNo Mod 2) = 0 Then
            lblBG.BackColor = Color.Cornsilk
            '/ หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 1 = เลขคี่
      Else
            lblBG.BackColor = Color.Azure
      End If

      '/ จากนี้มันก็กระโดดกลับไปที่ Sub FetchData เพื่ออ่านค่าเข้ามาพิมพ์ใหม่
      '/ หากหมดจำนวนแถวที่ต้องการพิมพ์ (นับจำนวนแถวใน DataGrid) ก็จะจบการทำงาน (EOF=True)
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / ทุกๆครั้งที่เริ่มต้นสั่งพิมพ์ จะต้องตั้งค่าเริ่มต้นใน ReportStart เพียงครั้งแรกและครั้งเดียว
    Private Sub AR6PrintEmployee_ReportStart(sender As Object, e As System.EventArgs) Handles Me.ReportStart
      '/ การตั้งค่าหน้ากระดาษ
      With PageSettings
            '/ หน่วยวัดเป็นนิ้ว (ใช้ CmToInch ด้วยการรับค่าเซนติเมตร แต่แปลงเป็นนิ้วแทน เพื่อวัดระยะได้ง่ายกว่า)
            .Margins.Left = CmToInch(1.5)
            .Margins.Right = CmToInch(0.2)
            .Margins.Top = CmToInch(1.5)
            .Margins.Bottom = CmToInch(1.5)
            ' ตั้งค่ากระดาษแนวตั้ง
            .Orientation = PageOrientation.Portrait
            ' กระดาษขนาด A4
            .PaperKind = Drawing.Printing.PaperKind.A4
            ' กรณีที่กำหนดขนาดกระดาษเอง
            ' .PaperKind = Drawing.Printing.PaperKind.Custom
      End With
      ' ปกติต้องเคลียร์ค่าต่างๆของ TextBox ก่อนการพิมพ์
      txtEmployeeID.Text = ""
      txtEmployeeName.Text = ""
      txtPosition.Text = ""
      txtDepartment.Text = ""
      txtSalary.Text = ""
    End Sub
End Class
ดาวน์โหลดชุดติดตั้ง ActiveReports .NET (V6) ได้ที่นี่ (เฉพาะสมาชิกเท่านั้น)
ดาวน์โหลดโค้ดต้นฉบับแบบเต็ม VB.NET (2010) ได้ที่นี่




apichit โพสต์ 2018-1-16 12:11:10

ขอบคุณครับอาจารย์

OUDONE โพสต์ 2022-10-18 21:21:37

แก้ไขครั้งสุดท้ายโดย OUDONE เมื่อ 2022-10-18 21:24

ขอบคุณครับอาจารย์ ที่มอบสิ่งดีดีให้
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] พื้นฐานการพิมพ์รายงานด้วย ActiveReports .NET ลงบนกระดาษขนาด A4