thongkorn โพสต์ 2018-6-19 13:14:48

[VB.NET] การพิมพ์รายงานด้วย ActiveReports .NET แบบวิธีการ UnBound Data

http://www.g2gnet.com/webboard/images/vbnet/ARUnbound.png


วิธีการ Bound Data และการ UnBound Data ได้กล่าวซ้ำๆไปหลายรอบแล้ว แอดมินเลยขอข้ามในส่วนนี้ไปนะครับ ตามปกติเราๆท่านๆก็มักจะใช้วิธี Bound โดยการเลือก Data Source เข้ามา จากนั้นก็นำ TextBox มาผูกเข้าไว้กับฟิลด์ข้อมูล ในขณะทำการออกแบบ หรือ Design Time ซึ่งวิธีการนี้มันง่าย รวดเร็วดี แต่มีข้อจำกัดอยู่หลายประการ ทำให้ขาดความยืดหยุ่นไป เช่น หากเราต้องการเปลี่ยน Data Source จาก MS Access ไปเป็น MySQL Server หรือหาก Data Source เกิดมีปัญหา ไฟล์พังหรือหายไป เอ้อเหรอ (Error) อย่างแน่นอน ทำให้เราต้องเริ่มกระบวนการใหม่ทั้งหมดแต่บทความนี้คือการไม่ผูกแหล่งจ่ายข้อมูล (Data Source) เอาไว้กับหน้ารายงานของ ActiveReports อ้าววว !!! แล้วมันผูกฟิลด์ข้อมูลเข้ากับ TextBox ได้อย่างไร ... แอดมินจะไล่เรียงการทำงานไปในแต่ละขั้นตอนให้ดูครับ

เริ่มจาก ReportStart ใน ActiveReports เพื่อทำการเชื่อมต่อฐานข้อมูล ... ปกติแล้วกระบวนการนี้เราจะเริ่มต้นมาตั้งแต่การเปิดฟอร์มหลัก แต่แอดมินนำมาแปะไว้เพื่อเป็นตัวอย่าง สำหรับท่านที่เผลอเข้ามาที่เว็บบอร์ดแห่งนี้ ต้องทำความเข้าใจในจุดประสงค์ของไฟล์ modDataBase.vb ซึ่งเป็นโมดูลเพื่อประกาศตัวแปรแบบ Public ด้วย เพราะว่าตัวแปรเหล่านี้เราจะต้องใช้งานมันบ่อยครั้งมากครับผม
    '// Start Here.
    Private Sub NewActiveReport1_ReportStart(sender As Object, e As System.EventArgs) Handles Me.ReportStart
      '/ การตั้งค่าหน้ากระดาษ
      With PageSettings
            '/ หน่วยวัดเป็นนิ้ว แต่ใช้การแปลงหน่วยด้วย CmToInch เข้าช่วย หากเราถนัดหน่วยวัด ซม.
            .Margins.Left = CmToInch(1) '// แปลงค่า 1.0 ซม. เป็นนิ้ว
            .Margins.Right = 0.1
            .Margins.Top = 1.0
            .Margins.Bottom = 0.2
            ' ตั้งค่ากระดาษแนวตั้ง
            .Orientation = PageOrientation.Portrait
            ' กระดาษขนาด A4
            .PaperKind = Drawing.Printing.PaperKind.A4
      End With

      '// เคลียร์ค่าก่อนการพิมพ์
      txtFullName.Text = ""
      txtNickName.Text = ""
      txtPositionName.Text = ""
      txtDepartmentName.Text = ""

      '// เริ่มต้นการเชื่อมต่อฐานข้อมูล
      Try
            '// Connect to DataBase. ปกติเราเชื่อมต่อฐานข้อมูลจากฟอร์มหลักมาเลยก็ได้
            Conn = ConnectDataBase()
            '// ทำการ Query ฟิลด์ข้อมูลที่ต้องการมาแสดงผล
            strSQL = _
                " SELECT tblContact.ContactPK, tblContact.Fullname, tblContact.Nickname, tblPosition.PositionName, tblDepartment.DepartmentName " & _
                " FROM tblDepartment INNER JOIN (tblPosition INNER JOIN tblContact ON tblPosition.PositionPK = tblContact.PositionFK) ON tblDepartment.DepartmentPK = tblContact.DepartmentFK " & _
                " ORDER BY ContactPK, FullName ASC "
            '// Open connection and create DataReader.   
            Cmd = New OleDbCommand(strSQL, Conn)
            If Conn.State = ConnectionState.Closed Then Conn.Open()
            DR = Cmd.ExecuteReader()

      Catch ex As Exception
            MessageBox.Show(ex.Message)
      End Try

    End Sub

สร้าง Field Collection ใน DataInitialize ... ก็เพราะเราไม่ได้ผูก Data Source จึงจำเป็นต้องสร้างฟิลด์ข้อมูลต่างๆขึ้นมาใหม่ ในตัวอย่างนี้จะใช้งานง่ายๆเพียง 4 ฟิลด์
    '// Add fields to the report's fields collection.
    Private Sub NewActiveReport1_DataInitialize(sender As Object, e As System.EventArgs) Handles Me.DataInitialize
      Fields.Add("FullName")
      Fields.Add("NickName")
      Fields.Add("PositionName")
      Fields.Add("DepartmentName")
    End Sub

การนำข้อมูลไปผูกเข้ากับฟิลด์ ใน FetchData ... การ Fetch ก็คือการเรียกข้อมูลเขามาใหม่ในแต่ละรายการ (Record) ที่เราทำการ Query เข้ามา หากข้อมูลนั้นยังไม่หมดรายการ หากค่า EOF (End Of File) = False (เท็จ) นั่นคือมันยังไม่หมดข้อมูล ก็จะนำค่าที่ Fetch เข้ามาไปพิมพ์ที่ Detail1_Format แต่หาก EOF = True (จริง) แสดงว่าไม่มีรายการข้อมูลที่จะพิมพ์ ก็จะไปที่ ReportEnd แทน เพื่อสิ้นสุดงานพิมพ์
    '// Retrieve information to populate the report fields.
    Private Sub NewActiveReport1_FetchData(sender As Object, eArgs As DataDynamics.ActiveReports.ActiveReport.FetchEventArgs) Handles Me.FetchData
      Try
            DR.Read()
            '// นำข้อมูลมาผูกเข้ากับฟิลด์ที่เรากำหนดบน ActiveReports
            Me.Fields("FullName").Value = DR("FullName")
            Me.Fields("NickName").Value = DR("NickName")
            Me.Fields("PositionName").Value = DR("PositionName")
            Me.Fields("DepartmentName").Value = DR("DepartmentName")
            '// ยังไม่หมดข้อมูล End Of File = เท็จ ... กระโดดไปพิมพ์ที่ Detail1_Format อีกครั้ง
            eArgs.EOF = False

      Catch ex As Exception
            '// แสดงว่าหมดข้อมูลแล้ว นั่นคือสิ้นสุดการพิมพ์
            eArgs.EOF = True
      End Try
    End Sub

การพิมพ์รายละเอียดใน Detail1_Format ... จากเหตุการณ์ FetchData หาก EOF = False มันจะเกิดการพิมพ์รายละเอียดของรายงานที่นี่
    '// หากเหตุการณ์ FetchData ทำให้ EOF = False แสดงว่ายังไม่หมดข้อมูล จะเกิดการพิมพ์ไปเรื่อยๆ
    Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format
      '// นำค่าจากฟิลด์ที่เรากำหนดมาแสดงผลใน TextBox ของ ActiveReports
      txtFullName.Text = Me.Fields("FullName").Value
      txtNickName.Text = Me.Fields("NickName").Value
      txtPositionName.Text = Me.Fields("PositionName").Value
      txtDepartmentName.Text = Me.Fields("DepartmentName").Value
    End Sub

โมดูลหากิน modDataBase.vb แอดมินทำการจัดเก็บตัวแปรที่สำคัญๆ และต้องใช้งานบ่อยๆเอาไว้ที่นี่ที่เดียว ดังนั้นจึงต้องประกาศตัวแปร และฟังค์ชั่นเป็นแบบ Public ทั้งหมด หมายความว่าทุกๆฟอร์ม จะสามารถมองเห็นได้ทั้งหมด
Imports System.Data.OleDb
Imports Microsoft.VisualBasic

Module modDataBase
    '// Declare variable one time but use many times.
    Public Conn As OleDbConnection
    Public Cmd As OleDbCommand
    Public DS As DataSet
    Public DR As OleDbDataReader
    Public DA As OleDbDataAdapter
    Public strSQL As String '// Major SQL
    Public strStmt As String    '// Minor SQL

    '// Data Path
    Public strPathData As String = MyPath(Application.StartupPath)
    '// Images Path
    'Public strPathImages As String = MyPath(Application.StartupPath)

    Public Function ConnectDataBase() As System.Data.OleDb.OleDbConnection
      strPathData = MyPath(Application.StartupPath) & "Data\"
      'strPathImages = MyPath(Application.StartupPath) & "Images\"
      Dim strConn As String = _
            "Provider = Microsoft.ACE.OLEDB.12.0;" & _
            "Data Source = " & strPathData & "Contact.accdb"

      Conn = New OleDb.OleDbConnection(strConn)
      ' Create Connection
      Conn.ConnectionString = strConn
      ' Return
      Return Conn
    End Function

    ' / --------------------------------------------------------------------------------
    ' / Get my project path
    ' / AppPath = C:\My Project\bin\debug
    ' / Replace "\bin\debug" with "\"
    ' / Return : C:\My Project\
    Function MyPath(AppPath As String) As String
      '/ MessageBox.Show(AppPath);
      AppPath = AppPath.ToLower()
      '/ Return Value
      MyPath = AppPath.Replace("\bin\debug", "\").Replace("\bin\release", "\").Replace("\bin\x86\debug", "\")
      '// If not found folder then put the \ (BackSlash) at the end.
      If Right(MyPath, 1) <> "\" Then MyPath = MyPath & "\"
    End Function
End Module

ฟอร์มหลักที่ใช้ในการ Preview รายงานของ ActiveReports ...
Public Class frmUnBoundData

    Private Sub btnPreview_Click(sender As System.Object, e As System.EventArgs) Handles btnPreview.Click
      '// ประกาศตัวแปร rpt จากหน้ารายงาน ActiveReports
      Dim rpt As New NewActiveReport1
      '// สั่งรัน
      rpt.Run()
      Me.Viewer1.ReportViewer.Zoom = 1    '(100%)
      '// แสดงผลรายงานเอกสาร
      Me.Viewer1.Document = rpt.Document
    End Sub

    Private Sub btnExit_Click(sender As System.Object, e As System.EventArgs) Handles btnExit.Click
      Me.Close()
    End Sub

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

End Class

Conclusion: จะเห็นได้ว่าการพิมพ์รายงานด้วย ActiveReports .NET นั้นไม่ได้ยากเย็นแสนเข็ญอะไรเลย มันจึงเป็นอีกหนึ่งทางเลือกของการทำรายงาน ... สวัสดี

ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่ ...


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

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