ผู้เขียน หัวข้อ: [VB.Net] แจกโค้ดการพิมพ์รายงานด้วย ActiveReports 6 (VB2010)  (อ่าน 484 ครั้ง)

ออฟไลน์ ทองก้อน ทับทิมกรอบ

  • Administrator
  • *****
  • กระทู้: 245
  • เพศ: ชาย
  • Webmaster G2GNet
[VB.Net] แจกโค้ดการพิมพ์รายงานด้วย ActiveReports 6 (VB2010)



แจกโค้ดการใช้งาน ActiveReports 2 ร่วมกับ Visual Basic 6 มาซ่ะเยอะ คราวนี้เป็น ActiveReports 6 ด้วย VB2010 ซึ่งมันก็ใช้หลักการเดียวกันนั่นแหละครับ ตัวอย่างที่จะนำมาเสนอให้ได้ชมกันนี้ ผมก็จะใช้ข้อมูลจาก ListView ซึ่งให้คุณลองจินตนาการภาพตามว่ามันมีแถว (Records) มีหลัก (Fields) ตามลักษณะของตารางข้อมูล ...



ก่อนอื่นผมขอแนะนำให้ปรับทัศนคติใหม่เกี่ยวกับเรื่อง Programming กันสักหน่อยครับ อย่าไปคิดแค่ว่าการจับลากมาวาง (Drag & Drop หรืออยู่ในสภาวะ Design Time) แล้วผูก Control ต่างๆเข้ากับก้อนข้อมูล แล้วมันจะทำให้ชิ้นงานมีความสมบูรณ์แบบ เพราะหากไปเจองานที่มีความสลับซับซ้อนมากขึ้น เดี๋ยวจะไปกันไม่เป็นน่ะครับ


หน้าจอการออกแบบบน AR6 Designer (ให้สังเกตว่ามันมีนามสกุล VB ก็หมายความว่ามันเสมือนเป็นฟอร์มๆหนึ่งใน Visual Basic ครับ)

ขอสรุปให้ฟังแบบสั้นๆก็คือ ... ทุกๆครั้งที่เรียกใช้งาน ActiveReport จะเริ่มกระบวนการขั้นตอนแรกที่ ReportStart (หรือ DataInitialize ก็ได้) ในการตั้งค่าหน้ากระดาษ เพียงครั้งแรกครั้งเดียวก่อนที่จะทำการพิมพ์ แต่หลังจากนั้น ...

หลักการที่สำคัญของ ActiveReports
(1) เริ่มการอ่านแถวข้อมูลเข้ามาจากโปรแกรมย่อย FetchData โดยทำการเปรียบเทียบค่าด้วยการนับรายการ (หากใช้ฐานข้อมูลจริง ส่วนนี้ก็จะใช้ในการทำกรุ๊ปด้วย)
(2) หากข้อมูลหรือจำนวนแถวยังไม่หมด นั่นคือ EOF = False ก็กระโดดมาทำการพิมพ์ที่ Detail1_Format หากหมดข้อมูลแล้ว EOF = True ก็จะสิ้นสุดกระบวนการพิมพ์
(3) กลับไปข้อที่ 1 อีกครั้ง เพื่อตรวจสอบว่ามีข้อมูลจะพิมพ์อีกหรือไม่
*** ขั้นตอนทั้งหมดนี้ คุณจะมองเห็นภาพได้อย่างชัดเจนเมื่อคุณใช้ Debugger เป็น ***

มาดูโค้ดกันเถอะ ... หากเปรียบเทียบกับ AR2 บน VB6 ก็จะเห็นได้ว่า "ไม่ได้แตกต่างกันเลย"

จาก AR6 Designer ชื่อ AR6PrintEmployee.vb
Imports DataDynamics.ActiveReports
Imports DataDynamics.ActiveReports.Document

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

    ' / -------------------------------------------------------------------------------------------------------------
    ' / เมื่อพิมพ์ข้อมูลจาก Detail1_Format เสร็จก็จะวนกลับมาเรียกข้อมูล (FetchData) ใหม่อีกครั้ง

    ' / ด้วยการเลื่อนค่าจำนวนแถวขึ้น ItemNo +1 แล้วเทียบกับจำนวนแถวใน ListView
    Private Sub AR6PrintEmployee_FetchData(sender As Object, eArgs As DataDynamics.ActiveReports.ActiveReport.FetchEventArgs) Handles Me.FetchData
        ItemNo = ItemNo + 1
        ' ตรวจสอบจำนวนการพิมพ์ทั้งหมด ด้วยการนับจำนวนแถวใน ListView ที่อยู่ในฟอร์มหลัก
        ' จะส่งค่าจำนวนแถวมาก็ได้ แต่ผมเลือกอ้างถึงตัว ListView ใน frmMain โดยตรง เพราะไม่เปลืองตัวแปร (Optimized)

        If ItemNo > frmMain.lvwEmployee.Items.Count Then
            ' หากหมดแล้วก็จบการพิมพ์
            eArgs.EOF = True
            Exit Sub
            ' ยังไม่หมดข้อมูล
        Else
            eArgs.EOF = False
        End If
    End Sub

    ' / -------------------------------------------------------------------------------------------------------------
    ' / รายละเอียดต่างๆก็จะนำมาแสดงใน Detail

    Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format
        ' การอ้างถึงค่าในแต่ละแถว, หลักของ ListView Control ที่อยู่ใน frmMain
        ' ค่า ItemNo เริ่มต้นจาก 1 แต่ลำดับแถวใน ListView จะเริ่มต้นจาก 0 (Index=0) ก็เลยต้องลบออกด้วย 1

        txtEmployeeID.Text = frmMain.lvwEmployee.Items(ItemNo - 1).SubItems(0).Text
        ' แถว 0 หลัก 1
        txtEmployeeName.Text = frmMain.lvwEmployee.Items(ItemNo - 1).SubItems(1).Text
        ' แถว 0 หลัก 2
        txtPosition.Text = frmMain.lvwEmployee.Items(ItemNo - 1).SubItems(2).Text
        ' แถว 0 หลัก 3
        txtDepartment.Text = frmMain.lvwEmployee.Items(ItemNo - 1).SubItems(3).Text
        ' จากนั้นก็เริ่มแถวใหม่(แต่หลักคงเดิม)

        ' หาเลขคู่กับเลขคี่ เพื่อพิมพ์ลาเบล lblBG สลับสีในการพิมพ์แต่ละแถว
        ' หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 0 = เลขคู่

        If (ItemNo Mod 2) = 0 Then
            lblBG.BackColor = Color.Cornsilk
            ' หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 1 = เลขคี่
        Else
            lblBG.BackColor = Color.Azure
        End If

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

    End Sub

Conslusion: ย้ำกันอีกครั้งทีว่านี่มันคือหลักการทำงานของ ActiveReports ครับผม หากคุณไม่เข้าใจก็จะไปต่อกันยากล่ะ

ดาวน์โหลดโค้ดต้นฉบับ VB2010

ดาวน์โหลด ActiveReports V6.2.3681 (สำหรับสมาชิกเท่านั้น)

วิธีการเรียกใช้งาน ActiveReports 6

บันทึกการเข้า
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

ออฟไลน์ Goii Pattarporn

  • Newbie
  • *
  • กระทู้: 4
Re: [VB.Net] แจกโค้ดการพิมพ์รายงานด้วย ActiveReports 6 (VB2010)
« ตอบกลับ #1 เมื่อ: ตุลาคม 20, 2015, 01:23:54 pm »
ถ้าดึงจาก DataGridView ทำเหมือนกันมัยค่ะ พอดีทำแล้วมัน ไม่วนลูป ให้ค่ะ

บันทึกการเข้า

ออฟไลน์ ทองก้อน ทับทิมกรอบ

  • Administrator
  • *****
  • กระทู้: 245
  • เพศ: ชาย
  • Webmaster G2GNet
Re: [VB.Net] แจกโค้ดการพิมพ์รายงานด้วย ActiveReports 6 (VB2010)
« ตอบกลับ #2 เมื่อ: ตุลาคม 20, 2015, 03:38:48 pm »
ถ้าดึงจาก DataGridView ทำเหมือนกันมัยค่ะ พอดีทำแล้วมัน ไม่วนลูป ให้ค่ะ



หลักการเหมือนกันหมดครับผม แตกต่างก็ตรงโค้ดในการควบคุม Control แต่ละตัวเท่านั้นเอง

โค้ดจากฟอร์มหลัก (frmMain) ให้เปลี่ยน ListView เป็น DataGridView แทน
    Private Sub frmMain_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
        With DataGridView1
            .AllowUserToAddRows = False
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.DisplayedCells
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .RowTemplate.Height = 26
            .MultiSelect = False
            .ColumnCount = 4
            .Columns(0).Name = "รหัสพนักงาน"
            .Columns(1).Name = "ชื่อ - นามสกุล"
            .Columns(2).Name = "ตำแหน่ง"
            .Columns(3).Name = "แผนก"
        End With

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

โค้ดจาก ActiveReports 6 Designer

Private Sub AR6PrintEmployee_FetchData(sender As Object, eArgs As DataDynamics.ActiveReports.ActiveReport.FetchEventArgs) Handles Me.FetchData
        ItemNo = ItemNo + 1
        ' ตรวจสอบจำนวนการพิมพ์ทั้งหมด ด้วยการนับจำนวนแถวใน DataGridView ที่อยู่ในฟอร์มหลัก
        If ItemNo > frmMain.DataGridView1.RowCount Then
            ' หากหมดแล้วก็จบการพิมพ์
            eArgs.EOF = True
            Exit Sub
            ' ยังไม่หมดข้อมูล
        Else
            eArgs.EOF = False
        End If
    End Sub

    ' / -----------------------------------------------------------------------------------------------
    ' / รายละเอียดต่างๆก็จะนำมาแสดงใน Detail

    Private Sub Detail1_Format(sender As System.Object, e As System.EventArgs) Handles Detail1.Format
        ' การอ้างถึงค่าในแต่ละแถว, หลักของ ListView Control ที่อยู่ใน frmMain
        ' ค่า ItemNo เริ่มต้นจาก 1 แต่ลำดับแถวใน DataGridView จะเริ่มต้นจาก 0 (Index=0) ก็เลยต้องลบออกด้วย 1

        txtEmployeeID.Text = frmMain.DataGridView1.Rows(ItemNo - 1).Cells(0).Value
        ' แถว 0 หลัก 1
        txtEmployeeName.Text = frmMain.DataGridView1.Rows(ItemNo - 1).Cells(1).Value
        ' แถว 0 หลัก 2
        txtPosition.Text = frmMain.DataGridView1.Rows(ItemNo - 1).Cells(2).Value
        ' แถว 0 หลัก 3
        txtDepartment.Text = frmMain.DataGridView1.Rows(ItemNo - 1).Cells(3).Value
        ' จากนั้นก็เริ่มแถวใหม่(แต่หลักคงเดิม)

        ' หาเลขคู่กับเลขคี่ เพื่อพิมพ์ลาเบล lblBG สลับสีในการพิมพ์แต่ละแถว
        ' หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 0 = เลขคู่

        If (ItemNo Mod 2) = 0 Then
            lblBG.BackColor = Color.Cornsilk
            ' หากเลขจำนวนใดๆหารด้วย 2 เหลือเศษ 1 = เลขคี่
        Else
            lblBG.BackColor = Color.Azure
        End If

    End Sub

ปกติก่อนงานพิมพ์ทุกครั้ง เราแทบจะต้องโหลดข้อมูลจากฐานข้อมูลใดๆมาแสดงผลไว้ที่ตารางกริดกันอยู่แล้ว ดังนั้นก็พิมพ์ออกจากเหล่าตารางกริดนี้ออกไปได้เลยครับ ...

บันทึกการเข้า
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

ออฟไลน์ Idear

  • Newbie
  • *
  • กระทู้: 2
Re: [VB.Net] แจกโค้ดการพิมพ์รายงานด้วย ActiveReports 6 (VB2010)
« ตอบกลับ #3 เมื่อ: กุมภาพันธ์ 09, 2016, 02:18:20 pm »
ขอบคุณครับอาจารย์

บันทึกการเข้า