[VB6] แจกโค้ดการใช้งานตารางกริด SharpGrid Bound Data Control ในแบบ Run Time
http://www.g2gnet.com/webboard/images/vb6/SGBoundDataRun.pngSharpGrid ActiveX Grid Control จัดเป็น Data Grid ที่ทรงประสิทธิภาพมาก สำหรับเหล่าบรรดา Developer ในกลุ่มของ Visual Studio 98 ทั้งนี้เราต้องใช้ทั้ง Design Time และการลงโค้ดตอน Run Time ผสมผสานกัน ถึงจะดึงขีดความสามารถของ ActiveX ตัวนี้ออกมาใช้งานได้อย่างเต็มที่ ...
ฟรีโค้ดของจริงนี้จะเป็นการนำเสนอ การใช้งาน SharpGrid ในลักษณะของ Bound Data Control หรือการผูกแหล่งข้อมูลเข้ากับตัวตารางกริด โดยการทำ Query เพื่อสร้าง DataSource ให้กับ SharpGrid แต่เป็นลักษณะของการเขียนโค้ดในแบบ Run-Time (สั่งรันจึงจะเห็นผล) โดยไม่ได้ใช้วิธีการที่จับลากมาวางแปะๆเหมือนตามตำรา ซึ่งแอดมินเชื่อว่าหลายๆคน อาจจะไม่ค่อยคุ้นเคยกันมากนักกับวิธีการแบบนี้ แต่เชื่อเถอะครับด้วยวิธีการออกแบบ และเขียนโค้ดในลักษณะนี้ มันจะมีความยืดหยุ่นที่สูงมากกว่า ยิ่งหากเราต้องทำงานในหลายๆโปรเจค ก็เรียกได้ว่าแค่ก็อปไปวางแปะได้เลย (หากเข้าใจแจ่มแจ้งนะขอรับ) ... หลักการทำงานของมัน เราสามารถนำไปเรียนรู้และใช้งานกับ VB.Net อย่างต่อเนื่องได้เลยทันที เพราะใช้หลักการเดียวกันครับผม (แค่คำที่เรียกใช้งานแตกต่างกัน) ...
มารู้จักกับคำว่า Bound Data และ UnBound Data Control
- Bound Data Control คือ การผูก (Bound) ตารางข้อมูล (RecordSet) เข้ากับพวก Component หรือ Control ต่างๆ ผ่านทาง DataSource กรณีที่นำมาใช้แสดงผลลงในตารางกริด มันจะอ่านค่าฟิลด์ต่างๆ เพื่อแสดงผลในแต่ละหลัก เรียงตามลำดับจากการ Query ที่เราเขียนไว้ และ ต้องแสดงทุกๆฟิลด์ออกมาทั้งหมด (หากไม่ต้องการแสดงผล จะต้องทำการซ่อนหลักของตัวกริดเอง) มีข้อดี คือ ทำงานได้เร็ว มักนำไปแสดงผลข้อมูลอย่างเดียว ซึ่งแอดมินจะใช้ในบทความนี้ทั้งหมดครับ
- UnBound Data Control ก็จะไม่มีการผูก (Unbound) ตารางข้อมูลใดๆเข้ากับ Component หรือ Control การนำไปใช้ในตารางกริด ไม่จำเป็นต้องแสดงผลออกมาทุกฟิลด์ และ จะเอาตัวไหนมาแสดงในหลักใดๆก่อนหลังก็ได้ มีข้อดี คือ ยืดหยุ่นมากกว่า และ มักใช้กับการแก้ไขข้อมูลของตารางกริดในแต่ละ Cell ได้นั่นเอง (อันนี้เดี๋ยวเป็นภาค 2 ต่อจากตอนนี้ครับ)
Download SharpGrid ActiveX/COM Grid Control (เฉพาะสมาชิกเท่านั้น)
หน้าตาของการออกแบบฟอร์ม (Design Time) ... ไม่ต้องปรับแต่งค่าคุณสมบัติ (Properties) ใดๆในตัว SharpGrid
http://www.g2gnet.com/webboard/images/vb6/SGBoundDataDesign.png
ก่อนที่จะทำการลงมือเขียนโปรแกรม จะต้องทำการ Reference หรืออ้างอิงการติดต่อกับฐานข้อมูลก่อน
http://www.g2gnet.com/webboard/images/vb6/SGReference.png
จากเมนู Project --> References ...
เรียกใช้งาน SharpGrid ActiveX Control ... เพื่อให้ SharpGrid มาปรากฏอยู่ใน ToolBox
http://www.g2gnet.com/webboard/images/vb6/SGComponent.png
จากเมนู Project --> Components ... เลือกแบบ Unicode เพื่อรองรับภาษาไทยได้
มาดูโค้ดกันเถอะ ... ในส่วนของฟอร์มหลัก
' / -----------------------------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand only)
' / Facebook: https://www.facebook.com/commonindy (World Wide)
' /
' / Purpose : Sample to use SharpGrid ActiveX for Bound Data Control.
' / Microsoft Visual Basic 6.0 Service Pack 6 + MS Access 2003
' / -----------------------------------------------------------------------------------------------
Option Explicit
' / -----------------------------------------------------------------------------------------------
Private Sub Form_Load()
' / -----------------------------------------------------------------------------------------------
'/ Trap Error
On Error GoTo ErrorHandler
'// การตั้งฟอร์มไว้กึ่งกลางจอภาพในแบบ Run Time
Me.Move (Screen.Width - Me.Width) \ 2, (Screen.Height - Me.Height) \ 2
'// ทำการติดต่อกับฐานข้อมูลก่อน (modDataBase.bas)
Call OpenDataBase
'// เคลียร์ค่า TextBox
txtSearch.Text = ""
'// ตั้งค่าการแสดงผล SharpGrid
Call InitSGGrid
'// ส่งค่า False เพื่อแจ้งโปรแกรมย่อยว่าแสดงผลข้อมูลออกมาทั้งหมด
Call SGGridEmployeeBound(False)
ExitProc:
Exit Sub
ErrorHandler:
MsgBox "Error : " & Err.Number & vbCrLf & Err.Description, vbOKOnly + vbExclamation, "รายงานความผิดพลาด"
Resume ExitProc
'
End Sub
' / -----------------------------------------------------------------------------------------------
Sub InitSGGrid()
' / -----------------------------------------------------------------------------------------------
' Initialize grid properties
With SGGridEmployee
'/ ++++++++++++++++++++++++++++++++++++++++
'/ กำหนดการแสดงผล GroupHeader หรือไม่
'/ False คือ ไม่ต้องแสดงผล
.GroupByBoxVisible = False
'/ True จะแสดงผล GroupHeader ซึ่งจะทำให้ผู้ใช้งานลาก Column ไปจัดกลุ่มได้
'/ ++++++++++++++++++++++++++++++++++++++++
.FitLastColumn = True
.Appearance = sg3D
.SpecialMode = sgModeListBox
.CellsBorderVisible = True
.AutoResize = sgAutoResizeColumns
.GroupIndentation = 225
.DefaultRowHeight = 390
.RowHeightMin = 390
.HeadingColCount = 1
.HeadingGridLinesColor = vbBlack
.HeadingGridLines = sgGridLineFlat
'/ สลับสีแถว
.EvenOddStyle = sgEvenOddRows
.ColorOdd = &HEFEFE0
.CellTips = sgCellTipsFloat
.CellTipsDelay = 400
.ScrollBarTips = sgScrollTipsVertical
.CacheAllRecords = True
.ColumnClickSort = True
'/ การแสดงผลปกติทั่วไป
With .Styles("Normal")
.BkgStyle = sgCellBkgSolid
.Font.Name = "Tahoma"
.Font.Size = 8
.Padding = 18
End With
'/ ส่วนหัวของ Header กรณีการแสดงผลทั่วไป
With .Styles("Heading")
.BackColor = RGB(0, 153, 255)
.ForeColor = vbWhite
.Font.Name = "Tahoma"
.Font.Size = 9
.Font.Bold = True
.Padding = 75
End With
'/ ส่วนหัวของ GroupHeader กรณีมีการจัดกลุ่ม
With .Styles("GroupHeader")
.Font.Size = 9
.Font.Bold = True
.BackColor = RGB(241, 239, 226)
.BkgStyle = sgCellBkgSolid
.Padding = 30
.BorderColor = RGB(241, 207, 0)
.Borders = sgCellBorderBottom
.BorderSize = 1
End With
'/ ส่วนของ GroupFooter กรณีมีการจัดกลุ่ม
With .Styles("GroupFooter")
.Font.Size = 9
.Font.Name = "Tahoma"
.ForeColor = vbBlue
.BackColor = RGB(255, 255, 224)
.BkgStyle = sgCellBkgSolid
.Padding = 75
.BorderColor = RGB(255, 207, 0)
.Borders = sgCellBorderBottom
.BorderSize = 50
.TextAlignment = sgAlignLeftCenter
End With
With .Styles("Tip")
.Font.Size = 10
.Padding = 40
End With
'/ กำหนดสีให้แถบแสงที่เราเลือกแถว
With .Styles("Selection")
.BackColor = RGB(0, 170, 0)
.ForeColor = vbWhite
.BkgStyle = sgCellBkgSolid
End With
'/ กำหนดสีให้แถบแสง กรณีที่เราไม่ได้เลือกแถวนั้น
With .Styles("InactiveSelection")
.BackColor = RGB(0, 170, 0)
.ForeColor = vbWhite
.BkgStyle = sgCellBkgSolid
End With
End With
End Sub
' / -----------------------------------------------------------------------------------------------
' / อ่านค่า Primary Key จากหลัก 0 ที่ถูกซ่อนเอาไว้ เพื่อนำไปใช้งานอย่างอื่นต่อไป
Private Sub SGGridEmployee_DblClick()
' / -----------------------------------------------------------------------------------------------
'/ กำหนดให้อยู่ที่หลัก 0 ก่อน
SGGridEmployee.Col = 0
' / อ่านค่าจากหลัก 0 และจากแถวที่เลือก (โดยไม่ต้องระบุแถวเลย)
MsgBox "EmployeePK = " & Val(SGGridEmployee.Text)
End Sub
' / -----------------------------------------------------------------------------------------------
' / ตัวแปร blnSearch เป็นออพชั่น หากไม่มีการส่งค่ามา ให้ถือว่ามันมีค่าเป็น FALSE
' / หาก blnSearch = False เป็นการแสดงผลข้อมูลทั้งหมด โดยไม่ต้องทำการค้นหา
' / หาก blnSearch = True เป็นการค้นหาข้อมูล ตามเงื่อนไขที่อยู่ใน TextBox
Sub SGGridEmployeeBound(Optional blnSearch As Boolean = False)
' / -----------------------------------------------------------------------------------------------
With SGGridEmployee
'.Columns.RemoveAll False
.DataRowCount = 0
' / หลัก 0 นี่คือหลักที่แสดงหมายเลขแถวครับ
.Rows.At(0).Height = 420
.ColumnClickSort = True
.Columns(0).Width = 400
.Columns(0).AllowSizing = False
.Columns(0).Hidden = True
.RowNumbering = False
End With
'/ สร้าง Instance ขึ้นมาใหม่ พร้อมตัดการเชื่อมต่อเดิมทิ้ง (หากลืม)
Set RS = New ADODB.Recordset
'/ blnSearch = True คือการค้นหาข้อมูล
If blnSearch Then
'// Bound Data จะแสดงผลโดยจัดเรียงข้อมูลตามฟิลด์ ที่อยู่ใน Query
'// หากฟิลด์ใดที่เราไม่ต้องการให้แสดงผล ต้องไปตั้งค่าหลักนั้นใน SharpGrid ให้ Hidden = True
Statement = _
" SELECT tblEmployee.EmployeePK, tblEmployee.EmployeeID, tblEmployee.EmployeeName, tblPosition.PositionName, " & _
" tblDepartment.DepartmentName, tblEmployee.DateStart, tblEmployee.Salary " & _
" FROM (tblEmployee INNER JOIN tblDepartment ON tblEmployee.DepartmentFK = tblDepartment.DepartmentPK) INNER JOIN " & _
" tblPosition ON tblEmployee.PositionFK = tblPosition.PositionPK " & _
" WHERE " & _
" ( " & " Like '%" & Trim(txtSearch.Text) & "%'" & " OR " & _
" " & " Like '%" & Trim(txtSearch.Text) & "%'" & " OR " & _
" " & " Like '%" & Trim(txtSearch.Text) & "%'" & " OR " & _
" " & " Like '%" & Trim(txtSearch.Text) & "%'" & ")" & _
" ORDER BY EmployeeID, EmployeeName "
'// blnSearch = False คือ แสดงผลทั้งหมด
Else
Statement = _
" SELECT tblEmployee.EmployeePK, tblEmployee.EmployeeID, tblEmployee.EmployeeName, tblPosition.PositionName, " & _
" tblDepartment.DepartmentName, tblEmployee.DateStart, tblEmployee.Salary " & _
" FROM (tblEmployee INNER JOIN tblDepartment ON tblEmployee.DepartmentFK = tblDepartment.DepartmentPK) INNER JOIN " & _
" tblPosition ON tblEmployee.PositionFK = tblPosition.PositionPK " & _
" ORDER BY DepartmentName, EmployeeID "
End If
' ============ IMPORTANT ==========
' / ระบุให้ทำงานในโหมด BOUND DATA
SGGridEmployee.DataMode = sgBound
' ==================================
RS.CursorLocation = adUseClient
'// adOpenForwardOnly และ adLockReadOnly เป็นการอ่านข้อมูลเดินหน้าอย่างเดียว จะมีความเร็วในการนำข้อมูลมาแสดงผล
RS.Open Statement, ConnDB, adOpenForwardOnly, adLockReadOnly, adCmdText
'/ =============== ผูกเข้ากับตาราง RecordSet ================
'/ เหมือนการกำหนด DataSource ใน VB.NET
Set SGGridEmployee.DataSource = RS
'/ ====================================================
'/ แสดงจำนวนรายการ
SGGridEmployee.DataRowCount = RS.RecordCount
If RS.RecordCount >= 0 Then
lblSearch.Caption = "[จำนวน : " & RS.RecordCount & " รายการ.]"
Else
lblSearch.Caption = "[จำนวน : 0" & " รายการ.]"
End If
'// จัดรูปแบบหลักใหม่
Call SetupSGGrid
' / Always must be disconnect RecordSet
RS.Close: Set RS = Nothing
End Sub
' / -----------------------------------------------------------------------------------------------
' / การตั้งค่าหลักต่างๆ ต้องให้ตรงกันกับฟิลด์ข้อมูลในการ Query จากโปรแกรมย่อย SGGridEmployeeBound
Private Sub SetupSGGrid()
' / -----------------------------------------------------------------------------------------------
'/ การกำหนดโหมด Bound Data ทำให้เกิดการนับจำนวนหลักเอาไว้ให้เรียบร้อย
' ================ Setup SGGrid ====================
With SGGridEmployee
'// Start Columns 1 โดยใช้ค่า Index ที่เรียงมาจาก Query
With .Columns(1)
'/ แสดงผลหัวข้อหลัก
.Caption = "EmployeePK"
'/ ความกว้างเป็น 0
.Width = 0
'/ ไม่ยอมให้ปรับขนาดความกว้างของหลัก
.AllowSizing = False
'/ เอาไปซ่อนจากสายตาผู้ใช้ไปเลย กรณีที่เราไม่ต้องการให้หลักนี้มีการแสดงผลให้ผู้ใช้งานเห็น
.Hidden = True
End With
' 2
With .Columns(2)
.Caption = "รหัสพนักงาน"
'/ ตั้งค่าการแสดงตำแหน่งของข้อมูล
.Style.TextAlignment = sgAlignLeftCenter
.HeadingStyle.TextAlignment = sgAlignLeftCenter
.AllowSizing = True
End With
' 3
With .Columns(3)
.Caption = "ชื่อ - นามสกุล"
.Style.TextAlignment = sgAlignLeftCenter
.HeadingStyle.TextAlignment = sgAlignLeftCenter
.AllowSizing = True
End With
' 4
With .Columns(4)
.Caption = "ตำแหน่ง"
.Style.TextAlignment = sgAlignLeftCenter
.HeadingStyle.TextAlignment = sgAlignLeftCenter
.AllowSizing = True
End With
' 5
With .Columns(5)
.Caption = "แผนก"
.Style.TextAlignment = sgAlignLeftCenter
.HeadingStyle.TextAlignment = sgAlignLeftCenter
.AllowSizing = True
End With
' 6
With .Columns(6)
.Caption = "วันที่เริ่มทำงาน"
.Style.TextAlignment = sgAlignRightCenter
.HeadingStyle.TextAlignment = sgAlignRightCenter
.Style.Format = "dd/mm/yyyy"
.AllowSizing = True
End With
' ใช้ชื่อฟิลด์ข้อมูลแทนหมายเลข Index แทนก็ได้
With .Columns("Salary")
.Caption = "เงินเดือน"
.Style.TextAlignment = sgAlignRightCenter
.HeadingStyle.TextAlignment = sgAlignRightCenter
.DataType = sgtCurrency
.Style.Format = "#,##0.00"
.AllowSizing = False
End With
'
End With
End Sub
' / -----------------------------------------------------------------------------------------------
' / กดปุ่ม Refresh เพื่อทำการแสดงผลข้อมูลทั้งหมด
Private Sub cmdRefresh_Click()
' / -----------------------------------------------------------------------------------------------
Call SGGridEmployeeBound(False)
With SGGridEmployee
.LeftCol = 0
.SetFocus
Sendkeys "{RIGHT}"
End With
txtSearch.Text = ""
End Sub
' / -----------------------------------------------------------------------------------------------
' / เมื่อคลิ๊กที่ปุ่มค้นหา
Private Sub cmdSearch_Click()
' / -----------------------------------------------------------------------------------------------
' / ตัดคำสงวน (Reserved Word) ที่มีปัญหากับฐานข้อมูลออกไป
txtSearch.Text = Replace(txtSearch.Text, "'", "")
txtSearch.Text = Replace(txtSearch.Text, "%", "")
txtSearch.Text = Replace(txtSearch.Text, "*", "")
If Trim(txtSearch.Text) = "" Or Len(txtSearch.Text) = 0 Then Exit Sub
'/ ทำการค้นหาข้อมูล
Call SGGridEmployeeBound(True)
End Sub
Private Sub txtSearch_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyDown Then Sendkeys "{TAB}"
If KeyCode = vbKeyUp Then Sendkeys "+{TAB}"
End Sub
Private Sub txtSearch_KeyPress(KeyAscii As Integer)
'// เกิดการกด Enter (ASCII Code มีค่าเท่ากับ 13 ฐาน 10)
If KeyAscii = 13 Then
Call cmdSearch_Click
'// ปิดเสียงด้วยการกำหนดให้ KeyAscii = 0 หรือไม่มีการกดคีย์ใดๆ
KeyAscii = 0
End If
End Sub
Private Sub cmdRefresh_KeyDown(KeyCode As Integer, Shift As Integer)
If KeyCode = vbKeyDown Or KeyCode = vbKeyRight Then Sendkeys "{TAB}"
If KeyCode = vbKeyUp Or KeyCode = vbKeyLeft Then Sendkeys "+{TAB}"
End Sub
Private Sub Form_Resize()
If Me.ScaleWidth < 120 Or Me.ScaleHeight < 120 Then Exit Sub
fraData.Height = Me.ScaleHeight - 60
fraData.Move 15, 0, Me.ScaleWidth - 15
SGGridEmployee.Move 15, 615, fraData.Width - (SGGridEmployee.Left) - 15, fraData.Height - 690
End Sub
Private Sub Form_Unload(Cancel As Integer)
On Error Resume Next
If Dir$(App.Path & "\*.tmp") <> "" Then Kill App.Path & "\*.tmp"
'/ ปิดการเชื่อมต่อกับฐานข้อมูล
Call CloseDataBase
End
End Sub
มาดูโค้ดในส่วนของโมดูลหลักที่เชื่อมต่อกับฐานข้อมูล ... (modDataBase.bas หรือ โมดูลหากิน)
' / -----------------------------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: https://www.facebook.com/g2gnet (For Thailand only)
' / Facebook: https://www.facebook.com/commonindy (World Wide)
' /
' / Purpose : Function to connect the MS Access DataBase.
' / Microsoft Visual Basic 6.0 Service Pack 6 + MS Access 2003
' / -----------------------------------------------------------------------------------------------
Option Explicit
'// ก่อนใช้งานต้องเลือก MDAC 2.8 มาจาก Project --> Refernces ก่อน
Global ConnDB As New ADODB.Connection
Global RS As New ADODB.Recordset ' / RecordSet หลัก
Global DS As New ADODB.Recordset ' / RecordSet สำรอง
Global RstData As New ADODB.Recordset ' / ใช้ในการพิมพ์รายงาน
Global Statement As String
Global SQLStmt As String
' / -----------------------------------------------------------------------------------------------
Public Sub OpenDataBase()
On Error GoTo Err_Handler
Dim DB_File As String
DB_File = App.Path
If Right$(DB_File, 1) <> "\" Then DB_File = DB_File & "\"
DB_File = DB_File & "DataBase.MDB"
' Open a connection.
Set ConnDB = New ADODB.Connection
ConnDB.ConnectionString = _
"Provider=Microsoft.Jet.OLEDB.4.0;" & _
"Data Source=" & DB_File & ";" & _
"Persist Security Info=False"
'" Jet OLEDB:Database Password=" & "password" & ";" '& _
'" Engine Type=5;"
ConnDB.Open
Exit Sub
Err_Handler:
MsgBox "Open Database Error : " & vbCrLf & Err.Number & " " & Err.Description
End
End Sub
Public Sub CloseDataBase()
' ตรวจสอบว่ามีการเชื่อมโยง - Connect ข้อมูลหรือไม่
If ConnDB.State = adStateOpen Then
ConnDB.Close
Set ConnDB = Nothing
End If
End Sub
' / -----------------------------------------------------------------------------------------------
' / ฟังค์ชั่นแก้ไขในการ SendKeys ซึ่งใน Windows 8+ 64 บิท จะมีปัญหา
Public Sub Sendkeys(Text As String, Optional Wait As Boolean = False)
Dim WshShell As Object
Set WshShell = CreateObject("Wscript.shell")
WshShell.Sendkeys Text, Wait
Set WshShell = Nothing
End Sub
Conslusion: อย่าเพียงแต่ลอกโค้ดแล้วไปสั่งรันให้ผ่านเท่านั้นนะครับ ต้องพยายามทำความเข้าใจในแต่ละชุดแถวคำสั่งที่สำคัญเอาไว้ให้ดีด้วย ซึ่งแอดมินได้พยายามเขียนคอมเมนท์ อธิบายในส่วนที่สำคัญๆเอาไว้ให้ได้อ่านกัน การใช้ Debugger เข้ามาช่วย จะทำให้เราสามารถเรียนรู้และเข้าใจหลักการทำงานต่างๆของโค้ดได้อย่างไม่ยากเย็น ... ขอให้โชคดี
Download SharpGrid ActiveX/COM Grid Control (เฉพาะสมาชิกเท่านั้น)
ดาวน์โหลดโค้ดต้นฉบับ VB6 ได้ที่นี่ ...
With .Styles("InactiveSelection")
.BackColor = RGB(0, 170, 0)
.ForeColor = vbWhite
.BkgStyle = sgCellBkgSolid
End With
กำลังหา InactiveSelection ตัวนี้อยู่ ขอบคุณมากครับผม ขอบคุณครับ
หน้า:
[1]