thongkorn โพสต์ 2018-3-23 14:31:31

[VB6] แจกโค้ดการใช้งานตารางกริด SharpGrid UnBound Data Control ในแบบ Run Time

http://www.g2gnet.com/webboard/images/vb6/SGUnboundDataRun.png


มารู้จักกับคำว่า Bound Data และ UnBound Data Control
- Bound Data Control คือ การผูก (Bound) ตารางข้อมูล (RecordSet) เข้ากับพวก Component หรือ Control ต่างๆ ผ่านทาง DataSource กรณีที่นำมาใช้แสดงผลลงในตารางกริด มันจะอ่านค่าฟิลด์ต่างๆ เพื่อแสดงผลในแต่ละหลัก เรียงตามลำดับจากการ Query ที่เราเขียนไว้ และ ต้องแสดงทุกๆฟิลด์ออกมาทั้งหมด (หากไม่ต้องการแสดงผล จะต้องทำการซ่อนหลักของตัวกริดเอง) มีข้อดี คือ ทำงานได้เร็ว มักนำไปแสดงผลข้อมูลอย่างเดียว (อ่านรายละเอียดและดาวน์โหลดโค้ดได้ที่นี่)


- UnBound Data Control ก็จะไม่มีการผูก (Unbound) ตารางข้อมูลใดๆเข้ากับ Component หรือ Control การนำไปใช้ในตารางกริด ไม่จำเป็นต้องแสดงผลออกมาทุกฟิลด์ และ จะเอาตัวไหนมาแสดงในหลักใดๆก่อนหลังก็ได้ มีข้อดี คือ ยืดหยุ่นมากกว่า และ มักใช้กับการแก้ไขข้อมูลของตารางกริดในแต่ละ Cell ได้นั่นเอง กรณีของ UnBound Data จะไม่ผูกแหล่งจ่าย หรือ DataSource เข้ากับตัว SharpGrid แต่จะอาศัยการวนลูป หรือการทำซ้ำแทน

Download SharpGrid ActiveX/COM Grid Control (เฉพาะสมาชิกเท่านั้น) ...


เพิ่มเติมจากวิธีการ BoundData วิธีการในการเข้าถึงข้อมูลในแต่ละเซลล์ เราสามารถใช้ Method CellAt(แถว, หลัก) เพื่อการเข้าถึงข้อมูลได้อย่างรวดเร็ว ...
' / -----------------------------------------------------------------------------------------------
' / อ่านค่า Primary Key จากหลัก 0 ที่ถูกซ่อนเอาไว้ เพื่อนำไปใช้งานอย่างอื่นต่อไป
Private Sub SGGridEmployee_DblClick()
' / -----------------------------------------------------------------------------------------------
    '// การเข้าถึงข้อมูลในแต่ละเซลล์ SharpGrid.CellAt(แถวที่เลือก, หลักที่ต้องการ)
    MsgBox "EmployeePK = " & SGGridEmployee.CellAt(SGGridEmployee.Row, 1) & vbCrLf & _
      "EmployeeName = " & SGGridEmployee.CellAt(SGGridEmployee.Row, 3)
End Sub
มาดูโค้ดส่วนของฟอร์มหลัก ...
' / -----------------------------------------------------------------------------------------------
' / 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 UnBound 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()
' / -----------------------------------------------------------------------------------------------
    '// การเข้าถึงข้อมูลในแต่ละเซลล์ SharpGrid.CellAt(แถวที่เลือก, หลักที่ต้องการ)
    MsgBox "EmployeePK = " & SGGridEmployee.CellAt(SGGridEmployee.Row, 1) & vbCrLf & _
      "EmployeeName = " & SGGridEmployee.CellAt(SGGridEmployee.Row, 3)
End Sub

' / -----------------------------------------------------------------------------------------------
' / ตัวแปร blnSearch เป็นออพชั่น หากไม่มีการส่งค่ามา ให้ถือว่ามันมีค่าเป็น FALSE
' / หาก blnSearch = False เป็นการแสดงผลข้อมูลทั้งหมด โดยไม่ต้องทำการค้นหา
' / หาก blnSearch = True เป็นการค้นหาข้อมูล ตามเงื่อนไขที่อยู่ใน TextBox
Sub SGGridEmployeeBound(Optional blnSearch As Boolean = False)
' / -----------------------------------------------------------------------------------------------
    With SGGridEmployee
      '.Columns.RemoveAll False
      '/ +++++++++++++++++++++++++++++++++++++++++++++++
      '/ ต้องกำหนดจำนวนหลักให้กับ SharpGrid กรณีที่ใช้งานแบบ UnBound
      '/ หากไม่ต้องการกำหนดจำนวน เราสามารถใช้ Method Add Column แทน
      .DataColCount = 7
      '/ +++++++++++++++++++++++++++++++++++++++++++++++
      .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 ==========
    ' / ระบุให้ทำงานในโหมด UNBOUND DATA
    SGGridEmployee.DataMode = sgUnbound
    ' ==================================
    RS.CursorLocation = adUseClient
    '// adOpenForwardOnly และ adLockReadOnly เป็นการอ่านข้อมูลเดินหน้าอย่างเดียว จะมีความเร็วในการนำข้อมูลมาแสดงผล
    RS.Open Statement, ConnDB, adOpenForwardOnly, adLockReadOnly, adCmdText
   
    '/ =============== ผูกเข้ากับตาราง RecordSet ================
    '/ BOUND DATA
    '/ เหมือนการกำหนด 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
   
    '// ++++++++++++++++++ UNBOUND DATA +++++++++++++++++++
    '// การ UnBound ก็คือการทำ Loop หรือการทำซ้ำ (Repetitive) นั่นเอง
    '// โดยที่เราเลือกมาเฉพาะบางฟิลด์ก็ได้ ไม่จำเป็นต้องนำมาจากการ Query ทั้งหมด
    Dim Rec As Long
    '// ที่เลือก FOR ก็เพราะว่ามันมีค่าเริ่มต้น - สิ้นสุด และมีการนับเพิ่ม (หรือลด) แบบคงที่
    '// ลองแก้ไขโดยใช้ Do While หรือ Do Until แทนครับผม
    For Rec = 1 To SGGridEmployee.DataRowCount
      With SGGridEmployee
            .CellAt(Rec, 1) = RS("EmployeePK")
            ' / การใส่ "" ไว้ด้านหน้าฟิลด์ข้อมูลแบบ String เพื่อป้องกัน Error หากมีค่าเป็น Null
            .CellAt(Rec, 2).Value = "" & RS("EmployeeID")
            .CellAt(Rec, 3).Value = "" & RS("EmployeeName")
            .CellAt(Rec, 4) = "" & RS("PositionName")
            .CellAt(Rec, 5) = "" & RS("DepartmentName")
            .CellAt(Rec, 6) = "" & Format(RS("DateStart"), "dd/MM/yyyy")
            .CellAt(Rec, 7) = Format(RS("Salary"), "#,##0.00")
      End With
      RS.MoveNext
    Next

    ' / 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
      ' 7
      With .Columns(7)
            .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
Conclusion: ก็คงจะเห็นได้ชัดเจนว่า ทั้งแบบ Bound หรือ UnBound ต่างก็แสดงผลได้เหมือนกัน แต่วิธีการ UnBound Data เหมาะสมกับการนำข้อมูลมาเพื่อทำการแก้ไขในตัวตารางกริด หากเปรียบเทียบกับ VB.NET ก็คงเหมือนกับการใช้งาน Data Reader นั่นเอง


ดาวน์โหลดโค้ดต้นฉบับ VB6 + SharpGrid ได้ที่นี่

หน้า: [1]
ดูในรูปแบบกติ: [VB6] แจกโค้ดการใช้งานตารางกริด SharpGrid UnBound Data Control ในแบบ Run Time