หน้าแรก อุปกรณ์ที่ประกอบเป็นเครื่องคอมพิวเตอร์ เกาเหลาเทคนิคการใช้ HTML วิธีทำสร้าง Shortcut บน Desktop ปัญหาใหญ่ของ Data transfer
หัวข้อนี้จะแนะนำคำสั่งนำรายงานที่สร้างโดย Crystal Report มาพิมพ์ใน VB สำหรับการสร้างรายงานนั้นท่านผู้อ่านต้องไปศึกษาเพิ่มเติม แต่ไม่ค่อยยากเพราะมี Wizard ช่วย ในความจริงแล้วผมเองไม่ค่อยชอบ Crytal Report เท่าไหร่เนื่องจากว่าพิมพ์ลงในแบบฟอร์ม(Preprint Form) จะค่อนข้างยาก แต่เท่าที่ทราบมาคือ Crystal Report Version 5.0 ได้สนับสนุนการพิมพ์ลงแบบฟอร์ม ปัจจุบันนี้ (เมษายน 41) Crystal Report เป็น Version 6 เนื่องจากว่า Crytal Report ที่มากับ VB4 เป็น Version 3 ซึ่งไม่ค่อยดีเท่าไหร่ ดังนั้นจึงอธิบายในส่วนที่เป็นของ VB5 ซึ่งเป็น Version 4.6 ซึ่งสามารถนำไปใน VB4 ได้ด้วย
เข้าใจโครงสร้างของรายงาน
ก่อนที่จะใช้ Crystal Report หรือ ทำรายงานเองก็ตามเราต้องเข้าใจโครงสร้างรายงานก่อน เรื่องโครงสร้างรายงานนั้นน่าน้อยใจอยู่มากก็คือ ไม่ค่อยมีการเรียน การสอนเลย แม้หนังสือไม่ค่อยจะมีเล่มใดกล่าวถึง คงถือว่าเป็นเรื่องเล็กน้อยมั้ง เมื่อก่อนที่จะมีโปรแกรมช่วยทำรายงานนั้นผม ต้องเขียนโปรแกรมตามรูปแบบตัวเอง แต่มาเจอหนังสือเล่มนึงอธิบายได้ดีมาก และเป็นพื้นฐานที่ใช้ในการทำรายงาน แม้กระทั่ง Crytal Report หรือ ใน Access หรือโปรแกรมอื่นที่ทำทางด้านรายงานก็มาจาก พื้นฐานนี้ ผมจึงต้องนำมากล่าวถึง ดังนี้
โครงสร้างรายงานมีดังนี้
Report Header ------------------------------------------------------------
Page Header ----------------------------------------------------------
Group Header --------------------------------------------------
Detail ---------------------------------------------------------
Group Footer ---------------------------------------------------
Page Footer -----------------------------------------------------------
Report Footer -------------------------------------------------------------
อธิายโครงสร้างรายงาน
Report Header / Title
ใช้ในการพิมพ์หน้าแรกหน้าเดียว ปกติในการพิมพ์รายงานในระบบเครือข่าย จะมีรายงานพิมพ์ต่อเนื่องกัน ถ้าเราไม่พิมพ์หน้าแรก เวลาจะไปแยกรายงาน จะทำให้สับสนได้ แต่ถ้าเป็นรายงานแบบ Sigle User ไม่ต้องพิมพ์หน้านี้ก็ได้
Page Header
ใช้พิมพ์หัวรายงานในแต่ละหน้า ทุกรายงานจำเป็นมากที่จะต้องมีคำอธิบายที่หัวรายงาน เช่น ชื่อบริษัท ชื่อรายงาน วันที่ เวลา และหัวรายงานของแต่ละช่อง ดังตัวอย่าง
บริษัท สาธิต จำกัด หน้า: 1
รายงานยอดขายตามวันที่ พิมพ์: 11/04/1998
วันที่ : 11/04/1998
--------------------------------------------------------------------------------------------------------------------------------------------------
วันที่ เลขที่ ชื่อลูกค้า จำนวนเงิน
--------------------------------------------------------------------------------------------------------------------------------------------------
Group Header
ใช้พิมพ์หัวกลุ่ม ซึ่งจะมีหลายกลุ่มก็ได้ เช่น ถ้าเราต้องการพิมพ์สรุปตาม หน่วยงาน และแผนก
Detail
ใช้พิมพ์รายการแต่ละบรรทัด
Group Footer
ใช้พิมพ์สรุปยอดรวมของแต่ละกลุ่ม ปกติมักจะเป็นยอดรวมจำนวนเงิน หรือ จำนวนรายการ
Page Footer
ใช้พิมพ์ท้ายรายงานของแต่ละหน้า ใช้มากในทางธุรกิจเช่นพิมพ์ใบกำกับภาษี
Report Footer / Summary
ใช้พิมพ์สรุปยอดรวมทั้งหมดท้ายรายงาน ทุกรายงานส่วนใหญ่ต้องมีพิมพ์สรุป ดังนั้นสำคัญมาก
เมื่อคุณเข้าใจโครงสร้างรายงานแล้ว เมื่อคุณไปใช้ Crytal Report ง่ายมากเลย เพียงคุณเลือกฟิลด์ไปใส่ตามแถบให้ถูกต้อง แต่ถ้าคุณหากคุณต้องเขียนโปรแกรมเอง ให้ดูตัวอย่างในหัวข้อเมื่อต้องการพิมพ์รายงานเอง
นำรายงาน Crytal Report มาใช้ใน VB ได้อย่างไร
ต้องเพิ่ม Control ของ Crytal Report เพิ่มเติม โดยไปที่ เมนู Tool -> Componet (VB4) หรือ เมนู Project -> Componet (VB5) ลากลงบน Form แล้วกำหนดคุณสมบัติ Report File Name เลือกรายงานที่สร้างจาก Crytal Report (นามสกุล .rpt) และกำหนดคุณสมบัติ Destination เมื่อต้องการพิมพ์ให้กำหนด Action = 1
ตัวอย่าง
Private Sub Command1_Click()
CrystalReport1.DataFiles(0) = "c:\vb32\biblio.mdb" '** กำหนดชื่อแฟ้มข้อมูล
CrystalReport1.ReportFileName = "c:\vb32\author.rpt" '** ใส่ชื่อรายงาน
CrystalReport1.Destination = 0 '** 0-ToWindow, 1-Printer, 2-File
CrystalReport1.Action = 1
End Sub
แค่นี้สามารถที่จะพิมพ์รายงาน Crystal Report ได้แล้ว
เมื่อต้องการเรียงลำดับฟิลด์
ในขั้นตอนออกแบบใน Crystal Report ท่านสามารถกำหนดให้เรียงลำดับได้เลย ในขั้นตอนของ Runtime ใช้ Sortfields
ตัวอย่าง
Private Sub Command1_Click()
CrystalReport1.DataFiles(0) = "c:\vb32\biblio.mdb"
CrystalReport1.ReportFileName = "c:\vb32\author.rpt"
CrystalReport1.Destination = 0
CrystalReport1.SortFields(0) = "+{authors.author}" '**+คือเรียงน้อยไปมาก Table=authors, Field=author
CrystalReport1.SortFields(1) = "-{authors.au_id}" '**-คือเรียงมากไปน้อย ของฟิลด์ที่ 2
CrystalReport1.Action = 1
End Sub
เมื่อต้องการเลือกเรคคอร์ดที่ต้องการพิมพ์
ในขั้นตอนออกแบบ ท่านสามารถกำหนดให้เลือกเรคคอร์ดได้แต่ไม่ค่อยเป็นที่นิยม เพราะควรจะให้ผู้ใช้เลือกพิมพ์ได้เอง ในขั้นตอนของ Runtime ใช้ SelectionFomula
ตัวอย่าง
Private Sub Command1_Click()
CrystalReport1.DataFiles(0) = "c:\vb32\biblio.mdb"
CrystalReport1.ReportFileName = "c:\vb32\author.rpt"
CrystalReport1.Destination = 0
CrystalReport1.SelectionFormula = " {authors.au_id} > 10 " '** เลือกฟิลด์ au_id ที่มากว่า 10
CrystalReport1.Action = 1
End Sub
เมื่อต้องการส่งค่าตัวแปรเข้าไปในรายงาน
ในการส่งค่าตัวแปรเข้าไปในรายงานเป็นเรื่องที่สำคัญเหมือนกัน เพราะเราจะได้ไม่ต้องเข่้าไปแก้ในรายงาน เช่น หัวรายงานต้องพิมพ์ชื่อบริษัท ซึ่งต้องเปลี่ยนเมื่อนำไปใช้กับบริษัทอื่น ดังนั้นท่านจะระบุตายตัวในรายงานไม่ได้ ต้องกำหนดเป็นตัวแปรไว้ แล้วใช้วิธีส่งค่าจาก VB เข้าไป
ในการส่งค่าตัวแปรนี้ท่านต้อง กำหนด Formulas ในรายงานก่อนแล้วใช้ Formulas
ตัวอย่าง
Private Sub Command1_Click()
CrystalReport1.DataFiles(0) = "c:\vb32\biblio.mdb"
CrystalReport1.ReportFileName = "c:\vb32\author.rpt"
CrystalReport1.Destination = 0
CrystalReport1.Formulas(0) = "Company = 'My Company' " '** กำหนด Company ไว้ในรายงาน
'CrystalReport1.Formulas(1) = "Total = {Orders.Sales} + {Orders.Vat} "
CrystalReport1.Action = 1
End Sub
เกี่ยวกับการจัดกลุ่ม
ปกติการจัดกลุ่มมักทำกัดที่ Design Time ใน Crytal Report เพราะว่าสามารถเห็นรายงานได้ทันที แต่ส่วนนี้อธิบายให้ทราบท่านนั้นเองว่าใช้อย่างไร มีใช้อยู่ 3 Properties คือ GroupCondition, GroupSelectionFormula และ GroupSortFields
GroupCondition กำหนดกลุ่มมีรูปแบบ
CrystalReport1.GroupCondition(0) = "Group;Field;Condition;SortDirection"
Group = ชื่อ; Field = ชื่อฟิลด์; Condition= เงื่อนไขการเรียง;SortDirect = A-น้อยไปมาก D-มากไปน้อย
เช่น
CrystalReport1.GroupCondition(0) = "Group1;{OrderH.OrderNo;ANYCHANGE;A"
GroupSelectionFormula ใช้เลือกกลุ่มที่จะใช้ในการพิมพ์รายงาน
GroupSortFileds ใช้ระบุกลุ่มของฟิลด์ที่ต้องการเรียงลำดับในการพิมพ์
Properties อื่นๆ
WIndowBorderStyle
กำหนดประเภทกรอบหน้าต่างเมื่อพิมพ์ออกทางจอภาพ
WindowControlBox
กำหนดให้มี Control Menu หรือไม่
WindowControl
กำหนดให้มีแถบเครื่องมือกรณีพิมพ์ออกทางจอ หรือไม่
WindowHeight
กำหนดความสูงหน้าต่างกรณีพิมพ์ออกทางจอภาพ ในหน่วย pixel
WindowWidth
กำหนดความกว้างหน้าต่างกรณีพิมพ์ออกทางจอภาพ ในหน่วย pixel
WindowLeft
กำหนดตำแหน่งกรอบด้านซ้ายของหน้าต่าง ในหน่วย pixel
WindowTop
กำหนดตำแหน่งกรอบด้านบนของหน้าต่าง ในหน่วย pixel
WindowState
กำหนดสถานะกรอบหน้าต่างเป็น Normal, Minimize หรือ Maximize
WindowParentHandle
กำหนดให้เป็นฟอร์มลูกของหน้าต่างอื่น
PrinterCopies
กำหนดจำนวนชุดของรายงาน
Printerฏพรอำพ
กำหนด Driver ของเครื่องพิมพ์
PrinterName
กำหนดชื่อเครื่องพิมพ์
PrinterPort
กำหนด Port การพิมพ์ เช่น LPT1
PrinterStartPage
กำหนดหน้าเริ่มพิมพ์
PrinterEndPage
กำหนดหน้าสุดท้ายที่จะพิมพ์
PrinterFileName
กำหนดชื่อแฟ้มที่จะพิมพ์ กรณีพิมพ์ออกทาง File
PrinterFileType
กำหนดประเภทแฟ้มที่พิมพ์ กรณีพิมพ์ออกทาง File สามารถพิมพ์ออกได้หลาย Format
ยังมีอีกหลาย Propperties ลองอ่านใน Help ดูละกัน
เมื่อต้องการพิมพ์รายงานเอง
เมื่อก่อนนี้เวลาเขียนรายงานผมมักจะเขียนตามรูปแบบตัวเอง แต่เมื่อทราบโครงสร้างรายงานแล้ว ทำให้ผมยึดรูปแบบนี้ไว้เป็นมาตรฐานเวลาแก้ไขปรับปรุงก็ง่าย และรูปแบบนี้จะใช้ได้ตลอดไม่ว่าจะเขียนด้วยภาษาใดก็ตาม
ดังนั้นผมจึงนำเสนอรูปแบบโครงสร้างรายงานให้ ถ้าจะนำไปใช้ต้องแก้ไขปรับปรุงอีกนิดนึง
ในตัวอย่างนี้ผมต้องการทำรายงานสรุปตามสาขา และ พนักงานขาย
Dim mDb As Database
Dim mRs As Recordset
Dim mLine As integer
Dim mPageLen as Integer
Dim mPageNo as Integer
Dim old_Branch As String
Dim old_SalesMan As String
DIm Sum_SalesMan as Currency
DIm Sum_Branch as Currency
DIm Sum_GrandTotal as Currency
'*** กำหนดค่าเริ่มต้น
mLine = 999
mPageLen = 40
mPageNo = 1
sum_GrandTotal = 0
'*** เปิดใช้ฐานข้อมูล
gSQL = " SELECT * FROM Order ORDER BY Order.Branch, Order.SalesMan; "
Set mDb = Workspaces(0).OpenDatabase("C:\Data\Data.MDB")
Set mRs = mDb.OpenRecordset(gSQL, dbOpenSnapshot)
'**** เริ่มพิมพ์
Printer.StartDoc
'***** Report Header
Do While Not mRs.EOF
If mLine > mPageLen - 2 Then
If mLine < 999 Then
Printer.NewPage '*** พิมพ์หน้าใหม่
mPageNo = mPageNo + 1
End If
Call PageHeader '*** พิมพ์หัวรายงาน (PageHeader เป็นโปรแกรมย่อย)
mLine = 1
End If
sum_Branch = 0
old_Branch = mRs!Branch
'***** Group Header
'***** พิมพ์หัวกลุ่ม ในที่นี้คือ Branch (อย่าลืมบวก mLine เพิ่ม)
'*****
Do While Not mRs.EOF And mRs!Branch = old_Branch
If mLine > mPageLen - 1 Then
Printer.NewPage '*** พิมพ์หน้าใหม่
mPageNo = mPageNo + 1
Call PageHeader '*** พิมพ์หัวรายงาน (PageHeader เป็นโปรแกรมย่อย)
mLine = 1
End If
sum_SalesMan = 0
old_SalesMan = mRs!SalesMan
'***** Group Header 2
'*** พิมพ์หัวกลุ่มย่อย ในที่นี้คือ พนักงานขาย (อย๋าลืมบวก mLine เพิ่ม)
'*****
Do While Not mRs.EOF And mRs!Branch = old_Branch And mRs!SalesMan = old_SalesMan
If mLine > mPageLen Then
Printer.NewPage '*** พิมพ์หน้าใหม่
mPageNo = mPageNo + 1
Call PageHeader '*** พิมพ์หัวรายงาน (PageHeader เป็นโปรแกรมย่อย)
mLine = 1
End If
'*** Detail
'*** พิมพ์ส่วนที่เป็นรายการ Detail
'***
'*** รวมยอดสะสม
sum_SalesMan = sum_SalesMan + mRs!Amount
sum_Branch = sum_Branch + mRs!Amount
sum_GrandTotal = sum_GrandTotal + mRs!Amount
'*** เพิ่มบรรทัด และ เลื่อนเรคคอร์ด
mLine = mLine + 1
mRs.MoveNext
If mRs.EOF Then Exit Do '*** แก้ไขกรณี Error เมื่อถึง Eof
Loop
'**** Group Footer 2
'**** พิมพ์สรุปยอดตามกลุ่มย่อย ในที่นี้คือ SalesMan อย่าลืมบวก mLine เพิ่ม
'****
If mRs.EOF Then Exit Do '*** แก้ไขกรณี Error เมื่อถึง Eof
Loop
'**** Group Footer
'**** พิมพ์สรุปยอดตามกลุ่ม ในที่นี้คือ Branch (อย่าลืมบวก mLine เพิ่ม)
'****
Loop
'**** Report Footer / Summary
'**** พิมพ์สรุปยอดทั้งสิ้น
'****
Printer.EndDoc
mRs.Close
mDb.Close
โครงสร้างนี้ถ้ามีพิมพ์สรุปยอดรวมในแต่ละหน้า ให้พิมพ์ ก่อนที่จะเรียก NewPage
ท่านผู้อ่านสามารถนำโครงสร้างนี้ไปปรับปรุงเพื่อพิมพ์รายงานได้ตามต้องการ และหวังว่าโครงสร้างนี้คงมีประโยช์นกับท่านไม่มากก็น้อย
ถ้าคุณต้องการพิมพ์ทางเครื่องพิมพ์ในรูปแบบ Text Mode
ใครที่เคยใช้ VB มาคงนึกไม่ถึง เพราะว่า VB เป็นโปรแกรมที่เขียนอยู่บน Windows คงพิมพ์ Text Mode ไม่ได้มั้ง ผมเองยังนึกไม่ถึงเลย มีคนถามนานแล้วว่า พิมพ์ Text Mode ได้หรือไม่ ? จนกระทั่งคุณ วรุตร์ Mail มาถามอีก ผมเลยต้องหาวิธึ จนได้ เลยมาแถลงให้คนอื่นได้ทราบกันทั่วหน้าเลย สำหรับการพิมพ์ใน Text Mode นั้นข้อดีคือเร็ว ดังนั้นถ้ารายงานใดยาวๆ ควรพิมพ์ใน Text Mode ก็จะดีมากOpen "LPT1:" For Output As #1
Print #1, "This is the line No.1..."
Print #1, "This is the line No.2..."
Print #1, "This is the line No.3..."
Close #1
การใช้แบบนี้จะส่งอักษรไปที่เครื่องพิมพ์ตรงๆ ดังนั้นคุณสามารถส่ง Control Code เพื่อควบคุม Printer ได้ในรูปแบบที่ต้องการ เหมือนกับที่สั่งจากโปรแกรมบน Dos แต่มีข้อเสียคือการพิมพ์ภาษาไทย คุณจะต้องจัดระดับเอง ผมเคยเขียนโปรแกรมจัดระดับบน Dbase แต่ว่าไม่รู้โปรแกรมหายไปไหนแล้ว หากใครเขียน ถ้้าส่ง Code มาบ้างจะขอบคุณมาก
หน้าแรก อุปกรณ์ที่ประกอบเป็นเครื่องคอมพิวเตอร์ เกาเหลาเทคนิคการใช้ HTML วิธีทำสร้าง Shortcut บน Desktop ปัญหาใหญ่ของ Data transfer