เพื่อนๆหลายคนในที่นี้ เมื่อเวลาพัฒนาโปรแกรมซึ่งต้องเก็บและแสดงรูปภาพ บางคนนิยมเก็บข้อมูลภาพในฐานข้อมูลเลย เพื่อความมั่นใจว่ารูปภาพจะไม่หายไป หรือโดนแก้ไขจากคนที่ไม่ได้รับอนุญาติ ซึ่งวิธีนี้ก็นับว่าเป็นวิธีการที่ดี แต่ค่อนข้างกินทรัพยากรเครื่องพอสมควรทีเดียว
บางท่านนิยมเก็บไฟล์รูปภาพไว้ใน Folder แล้วเก็บ file path ไว้ในฐานข้อมูลแทน ซึ่งถ้ากำหนดสิทธิและบริหารข้อมูลที่ดีก็ไม่มีปัญหาในการใช้งาน ซึ่งรูปที่เก็บไว้เราสามารถนำมาแสดงบน form ของ VB ได้อย่างง่ายดาย แต่ถ้าเราต้องการนำรุปภาพมาแสดงใน Crystal Report ก็คงต้องใช้ลูกเล่นเพิ่มเติมนิดหน่อยครับ
เพราะใน Crystal Report สามารถใส่รูปภาพได้โดยใช้ Picture Field หรือ OLE แต่มันเป็น Static ไม่สามารถเปลี่ยนรูปตาม record ที่เกิดขึ้นได้ นอกจากจะใช้ field ประเภท IBOLBFieldObject แสดงข้อมูล BLOB Data Type จากฐานข้อมูล
ซึ่งใน MS-Access เราต้องกำหนด field type เป็น OLE ครับ ส่วนใน MS-SQL Server ก็กำหนดเป็น Image ส่วน Oracle ก็เป็น BLOB
เอาละสมมติว่าตอนนี้ผมมีฐานข้อมูลสินค้าซึ่งเก็บใน MS-Access ใช้ VB เป็น Front End และ Crystal Report เป็น ตัวแสดงรายงาน ในฐานข้อมูลผมเก็บข้อมูลรูปภาพของสินค้าเป็น file path แทนครับ ทีนี้พอผมจะต้องการพิมพ์รายงานสินค้าพร้อมรูป โดยทำ form ให้ user พิมพ์รหัสสินค้าที่
เมื่อ user กดปุ่ม พิมพ์ ผมก็ทำดังนี้
1.) สร้าง Temp Table ขึ้นมาก่อนโดยให้ชื่อว่า tblTemp ผ่านคำสั่ง "CREATE TABLE" ของ SQL Command โดยในตัวอย่างนี้ผมสร้างตารางที่มี 2 ฟิลด์ คือ ID สำหรับเก็บรหัสสินค้า เป็น Primary Key กับ ฟิลด์ JewPic เป็นข้อมูลประเภท OLE เพื่อเก็บรูปภาพครับ
หรือ
ถ้าไม่ถนัดเราอาจสร้างตารางไว้ก่อนเลย แล้วแค่ไปเคลียร์ข้อมูลในตารางนี้ทิ้งก่อนก็ได้ครับ โดยใช้คำสั่ง "DELETE FROM ...."
2.) อ่าน file path ที่รหัสสินค้าตรงกันในฐานข้อมูล จากนั้นก็ไปแปลงไฟล์รูปภาพ เป็นข้อมูลไบนารี แล้วเก็บไว้ในฐานข้อมูลที่สร้างขึ้น ลองดู source code ด้านล่างครับ
2.1) ประกาศตัวแปรก่อนเลยครับ
Dim myCon As New ADODB.Connection
Dim myRST As New ADODB.Recordset
Dim strSQL As String
Dim strCON As String
Dim lngLength As Long
Dim lngBuffer As Long
Dim lngRemain As Long
Dim bPic() As Byte
Dim i As Integer
Const Buffer = 8192
Dim Handle As Integer
จุดสังเกต bPic() เป็น array ที่เก็บข้อมูลเป็น Byte ครับ
2.2) ช่วงต่อมาเป็นการทดสอบข้อมูลรหัสสินค้าที่ user คีย์เข้ามา
If Not IsNumeric(Text1) Then
MsgBox "Please enter ID number"
Exit Sub
End If
strCON = "Provider=Microsoft.Jet.OLEDB.4.0;Data Source=C:\Documents and Settings\nithi.MOLLD\Desktop\myJew.mdb;Persist Security Info=False"
strSQL = "SELECT * FROM tblJewelry WHERE ID=" & Me.Text1
myRST.Open strSQL, strCON, adOpenForwardOnly, adLockPessimistic
If myRST.EOF Then
MsgBox "No data"
Else
2.3) ถ้าuser คีย์รหัสสินค้าถูกต้องก็ให้
' ***** เปิด tempTable เพื่อเตรียมใส่รูป ******
Dim myRST2 As New ADODB.Recordset
strSQL = "SELECT * FROM tblTemp WHERE ID=" & Text1
myRST2.Open strSQL, strCON, adOpenDynamic, adLockOptimistic
If myRST2.EOF Then
myRST2.AddNew
myRST2("ID") = Text1
End If
' ******** เปิดไฟล์รูปภาพเป็นแบบไบนารี ********
Handle = FreeFile
Open myRST("PicPath") For Binary As #Handle
lngLength = LOF(Handle)
If lngLength = 0 Then
Close #Handle
MsgBox "Empty file."
Else
' ***** เริ่มต้นตัดไฟล์เก็บเข้าฐานข้อมูล *****
lngBuffer = lngLength / Buffer ' หาจำนวนครั้งของการใส่ข้อมูลจำนวนขนาด buffer (8192)
lngRemain = lngLength Mod Buffer ' จำนวนเศษที่เหลือ
ReDim bPic(lngRemain) 'ประกาศขนาดของ array ตามขนาดเศษที่เหลือก่อน
Get #Handle, , bPic() ' อ่านข้อมูลจากไฟล์ที่เปิดไว้เก็บเข้า array
myRST2("JewPic").AppendChunk bPic() 'นำข้อมูลใน array ไปเก็บไว้ใน field ของ recordset
ReDim bPic(Buffer) ' ประกาศขนาดของ array ใหม่ให้ตามขนาดของ buffer คือ 8192
' ***** วนรอบเพื่อใส่ข้อมูลเพิ่มเข้า recordset *****
For i = 1 To lngBuffer
Get #Handle, , bPic()
myRST2("JewPic").AppendChunk bPic()
Next
' ***** เมื่อใส่ข้อมูลครบทั้งหมด ก็ทำการ update recordset *****
myRST2.Update
End If
' **** เสร็จงานแล้วก็ คืน memory ให้ระบบด้วยจ้า *****
myRST2.Close
Set myRST2 = Nothing
Close #Handle
End If
myRST.Close
Set myRST = Nothing
Set myCon = Nothing
3.) เสร็จแล้วก็ให้เปิดรายงาน Crystal Report ได้เลยครับ อ้อ ใน Crystal Report ให้นำตาราง temp ที่สร้างขึ้นมาทำการ เชื่อมด้วยครับ
SELECT * FROM tblJewelry LEFT JOIN tblTemp on tblJewelry.ID=tblTemp.ID
เพิ่มเติม
1. ลองทำแบบเลือกข้อมูลทีละหลายๆข้อมูลใน VB ครับ ในตัวอย่าง souce code จะเป็นแบบเลือกรายงานทีละเรคอร์ดเดียวครับ แต่ตัวรายงานผมโชว์หลายเรคคอร์ดเพื่อแสดงว่ารูปจะเปลี่ยนไปตามแต่ละ record ครับ
2. ถ้ามีวิธีอื่นที่ดีกว่านี้ก็ ส่งมาให้อ่านกันบ้างนะครับ