พื้นฐานในการใช้งาน MS FlexGrid ก่อนสร้างความสัมพันธ์แบบ One To Many (ภาค 1)

Category »  VB 6/VB.Net
โดย : Webmaster เมื่อ 2/3/2553   เวลา: 14:33
(อ่าน : 16372) 
การออกแบบตารางข้อมูลแบบ One To Many

มีพี่น้องหลายคน ถามผมมาเกี่ยวกับเรื่องของใบขายสินค้า 1 ใบ มีลูกค้า 1 ราย แต่ใบขายสินค้า 1 ใบ มีสินค้าได้มากกว่า 1 ชนิด จะต้องออกแบบตารางข้อมูลได้อย่างไร ... คำถามแบบนี้เป็นการสร้างคำถามให้คนตอบงงเล่น 55555+ ... คำตอบก็คือ ให้มองเข้ามาทีละส่วน โดยแบ่งแยกย่อยออกมา จากคำถามผมก็สรุปใหม่ คือ ใบขาย 1 ใบ ขายให้ลูกค้า 1 ราย แต่สามารถขายสินค้าได้หลายตัว ... ดังนั้นใบขาย (ใบนี้) กับ ลูกค้า (รายนี้) มันคือความสัมพันธ์แบบ 1 : 1 ... หากเรามองมาที่ ใบขาย 1 ใบ กับ สินค้าหลายตัว ก็จะทำให้เห็นความสัมพันธ์ในแบบ One To Many การแยกย่อยก็จะพอทำให้มองเห็น (ลางๆ) ในงานออกแบบตารางข้อมูลได้บ้างแล้ว ... แต่เวลาที่ผมถ่ายทอดความรู้ให้กับเหล่าลูกศิษย์ของผมเอง ผมจะยังไม่เข้าประเด็นในการออกแบบตารางข้อมูล เพราะสิ่งที่อยากจะให้คิด หรือ ศึกษา ไว้เป็นพื้นฐาน ก็คือ จะทำอย่างไรให้ตารางกริดมันสามารถรับข้อมูลเข้ามา (หรือลบออก) และ แสดงผลให้ได้หลายๆแถว เสียก่อนต่างหากล่ะ ... หากไม่สาธยายความถึงเรื่องนี้ก่อน รับรองเลยครับ ตอนที่ไปเกี่ยวข้องกับการทำ QUERY ข้อมูล จะยิ่งติดปัญหามากกว่านี้ เพราะผู้เรียนจะพะวงทั้ง 2 ด้าน ... บทความนี้จะแนะแนวทางวิธีการคิด และ ฝึกทักษะ เพื่อควบคุมตารางกริดให้ได้ก่อน แล้วค่อยมาลงในส่วน DataBase ต่อไป

ขอย้ำว่า นี่คือวิธีการถ่ายทอดความรู้ หรือ การสอนของผมนั่นเองแหละครับ แต่มันก็คงจะไม่เหมือนตอนที่บรรยายผ่านหน้าจอหรอกน่ะครับผม

ดาวน์โหลด
ดาวน์โหลด Source Code สำหรับ MS Visual Basic 6.0 - Service Pack 6
 ดาวน์โหลด Visual Basic 6.0 SP5: Run-Time Redistribution Pack
 ดาวน์โหลด Microsoft Data Access Object (MDAC) และ Jet 4.0 Update
 ดาวน์โหลด Microsoft Visual Basic Service Pack 6
ข้อมูลเพิ่มเติม
ตารางกริด (MS Flex Grid) ธรรมดา ที่ไม่ธรรมดา ... VB 6.0
การอ่านข้อมูลแบบ Text File เข้าสู่ MS FlexGrid ด้วย MS Visual Basic 6.0
ตารางกริด (MS Flex Grid) ธรรมดา ที่ไม่ธรรมดา ... ตอนการจัดเรียงข้อมูลในการแสดงผลให้ MS FlexGrid
ตารางกริด (MS Flex Grid) ธรรมดา ที่ไม่ธรรมดา ... ตอนใช้ Wheel Mouse ใน MS FlexGrid
ตารางกริด (MS Flex Grid) ธรรมดา ที่ไม่ธรรมดา ... ตอนจับยัดข้อมูลเข้าไปใน MS FlexGrid ได้
พื้นฐานในการใช้งาน MS FlexGrid ก่อนสร้างความสัมพันธ์แบบ One To Many (ภาค 2)
เริ่มต้นกระบวนการทำงาน

Projects --> Component ...


การนำเสนอให้กับผู้เรียนเพื่อทำความเข้าใจในหลักการของการเพิ่ม-ลบแถว ในแบบพื้นฐาน
โค้ดแบบพื้นฐาน - เพื่อนำทางให้ผู้เรียน

Option Explicit

' ลบแถว
Private Sub cmdDeleteRow_Click()
    ' หากเหลือเพียง Column Header อยู่เพียง 1 แถว ให้ออกไปจากโปรแกรมย่อยทันที
    If fgData.Rows = 1 Then Exit Sub
    
    ' หากเหลือเพียง 2 แถว ประกอบด้วย Column Header และ ข้อมูล 1 แถว
    If fgData.Rows = 2 And fgData.Row = 1 Then
        ' กำหนดให้ MS FlexGrid เหลือเพียง Column Header โดยอัตโนมัติ
        fgData.Rows = 1
        Exit Sub
    End If
     
    ' หาก MS FlexGrid ไม่ตรงกับเงื่อนไขทางด้านบนสักตัว
    ' ก็ให้ลบแถวปัจจุบันของ MS FlexGrid ออกไปได้เลย โดยใช้ RemoveItem Method
    fgData.RemoveItem fgData.Row

End Sub

' เพิ่มแถว
Private Sub cmdAddRow_Click()
    Dim sRow As Integer
    
    ' เพิ่มจำนวนแถวใน MS FlexGrid อีก 1 แถว
    fgData.Rows = fgData.Rows + 1
    ' ให้แถวปัจจุบันลดลง 1 (เพื่อไม่ให้นับ Column Header)
    sRow = fgData.Rows - 1
    
    ' ใส่ข้อมูลสมมุติเข้าไปตามแถวที่เพิ่มขึ้นมา
    fgData.TextMatrix(sRow, 0) = sRow

End Sub

' ทดสอบตั้งค่าแถวไว้รอก่อน
Private Sub Form_Load()
    Dim i As Integer
    fgData.Rows = 4
    fgData.Cols = 1
    fgData.FixedCols = 0
    fgData.FixedRows = 1
    
    ' ตั้งค่าสมมุติเพื่อทดสอบการแสดงผล
    For i = 1 To 3
        fgData.TextMatrix(i, 0) = i
    Next
End Sub
นี่คือการนำเสนอหลักการ และ วิธีคิดให้กับผู้เรียนได้ศึกษา ให้เข้าใจในเรื่องของเหตุการณ์ (Event) ที่เกิดขึ้น และ มันต้องใช้คำสั่ง หรือ Method ใดบ้าง หลังจากนั้นก็อาจจะให้เป็นงานไปฝึกทำ โดยให้แสดงผลข้อมูลตามภาพด้านล่าง ที่สำคัญจะต้องมีตัวอย่างหน้าจอโปรแกรมให้ผู้เรียนดูด้วย ไม่ใช่สั่งงานกันแบบกลางอากาศ เพื่อให้ผู้เรียนได้จินตนาการคิดกันไปเอาเอง ระดับมือใหม่น่ะครับ ... เขา (หรือเธอ) ไม่ใช่เทวดา นางฟ้า ที่หล่นตุ๊บลงมาจากสวรรค์ชั้นไหน 55555+ ... อีกทั้งในกระบวนการการเรียนรู้ (แทบทุกอย่าง) นั้น "ไม่มีอะไรจะดีสู้ของจริง" ไปได้หรอกครับพี่น้อง

คราวนี้มาดูการพัฒนาก้าวหน้าไปอีกขั้น

Design Time


Run Time

โค้ดตัวอย่างการฝึกทักษะในการควบคุมข้อมูล และการทำงานต่างๆของตารางกริด

Option Explicit

' ======================================================
' การเพิ่มแถวใน MS FlexGrid
' ======================================================
Private Sub cmdAddRow_Click()
    Dim CurrentRow As Integer
    
    ' เพิ่มจำนวนแถวใน MS FlexGrid อีก 1 แถว
    fgData.Rows = fgData.Rows + 1
    ' ให้แถวปัจจุบันลดลง 1 (เพื่อไม่ให้นับ Column Header)
    CurrentRow = fgData.Rows - 1
    
    ' แถวใหม่ที่เพิ่มเข้ามา ทำการตั้งค่าข้อมูล (สมมุติ) ให้ดู
    Randomize
    fgData.TextMatrix(CurrentRow, 0) = CurrentRow
    fgData.TextMatrix(CurrentRow, 1) = Chr$(Int(Rnd() * 26) + 65) & Int(100 * Rnd)
    fgData.TextMatrix(CurrentRow, 2) = Format(Int(10000 * Rnd), "0.00")
    ' ใส่จำนวนสินค้าครั้งละ 1 ชิ้น
    fgData.TextMatrix(CurrentRow, 3) = 1
    fgData.TextMatrix(CurrentRow, 4) = Format(fgData.TextMatrix(CurrentRow, 2) * _
                        fgData.TextMatrix(CurrentRow, 3), "0.00")

    ' บังคับให้ Focus ไปที่ MS FlexGrid
    fgData.SetFocus
    SendKeys "{DOWN}"

End Sub

' ======================================================
' การลบแถวรายการออกไป
' ======================================================
Private Sub cmdDeleteRow_Click()
    ' หากเหลือเพียง Column Header อยู่เพียง 1 แถว ให้ออกไปจากโปรแกรมย่อยทันที
    If fgData.Rows = 1 Then Exit Sub
    
    ' หากเหลือเพียง 2 แถว ประกอบด้วย Column Header และ ข้อมูล 1 แถว
    If fgData.Rows = 2 And fgData.Row = 1 Then
        ' กำหนดให้ MS FlexGrid เหลือเพียง Column Header โดยอัตโนมัติ
        fgData.Rows = 1
        Exit Sub
    End If
     
    ' หาก MS FlexGrid ไม่ตรงกับเงื่อนไขทางด้านบนสักตัว
    ' ก็ให้ลบแถวปัจจุบันของ MS FlexGrid ออกไปได้เลย โดยใช้ RemoveItem Method
    fgData.RemoveItem fgData.Row

    ' บังคับให้ Focus ไปที่ MS FlexGrid
    fgData.SetFocus
    SendKeys "{DOWN}"

End Sub

Private Sub Form_Load()
    Me.Move (Screen.Width - Width) \ 2, (Screen.Height - Height) \ 2
    
    ' ตั้งค่าต่างๆให้กับ MS FlexGrid แบบ Run Time
    Call SetupGrid
    
    ' บังคับให้ Focus ไปที่ MS FlexGrid
    SendKeys "{UP}"

End Sub

' ======================================================
' การตั้งค่าคุณสมบัติของ MS FlexGrid ในลักษณะของ Run Time
' ======================================================
Sub SetupGrid()
    With fgData
        
        .FixedRows = 1
        .FixedCols = 0
        
        ' จำนวนหลักทั้งหมด
        .Cols = 5
        ' ตั้งค่าเริ่มต้นจำนวนแถวทั้งหมดเป็น 1 (เฉพาะ Column Header)
        .Rows = 1
        ' การใช้งานจริงๆ เราใช้หลักแรก (หลัก 0) เพื่อทำการซ่อน Primary Key ไม่ให้ User มองเห็น
        .ColWidth(0) = 0
        .ColWidth(1) = .Width \ 4 - 100
        .ColWidth(2) = .Width \ 4 - 200
        .ColWidth(3) = .Width \ 4 - 100
        .ColWidth(4) = .Width \ 4
        
        .TextMatrix(0, 0) = "PK"
        .TextMatrix(0, 1) = "รหัสสินค้า"
        .TextMatrix(0, 2) = "ราคาสินค้า"
        .TextMatrix(0, 3) = "จำนวน"
        .TextMatrix(0, 4) = "รวมจำนวนเงิน"
    End With
    
    With fgData
        .RowHeightMin = 330
        .SelectionMode = flexSelectionByRow ' Focus แบบเลือกทั้งแถว
        .AllowUserResizing = flexResizeNone ' ไม่อนุญาตให้ปรับขนาดของแถวหรือหลักได้
        .HighLight = flexHighlightWithFocus
        
        ' ปรับตำแหน่งของการแสดงผล
        .FixedAlignment(1) = flexAlignLeftCenter
        .ColAlignment(1) = flexAlignLeftCenter
        .FixedAlignment(2) = flexAlignRightCenter
        .ColAlignment(2) = flexAlignRightCenter
        .FixedAlignment(3) = flexAlignRightCenter
        .ColAlignment(3) = flexAlignRightCenter
        .FixedAlignment(4) = flexAlignRightCenter
        .ColAlignment(4) = flexAlignRightCenter
    
        ' ปรับค่าแสดงผลด้านสี
        .BackColorFixed = RGB(133, 175, 255)
        .ForeColorFixed = vbBlack
        .BackColorBkg = RGB(245, 245, 245)
        .BackColorSel = RGB(121, 255, 53)
        .ForeColorSel = vbBlack
        .BackColor = RGB(255, 255, 204)
        .ForeColor = vbBlack
        .GridColor = vbBlack
    
    End With

End Sub
จะเห็นได้เลยว่ายังคงใช้หลักการเดิมในการเพิ่ม หรือ ลบแถวข้อมูลออกไป สิ่งที่เพิ่มขึ้นมาอีก ก็คือ การกำหนดคุณสมบัติต่างๆของ MS FlexGrid ในลักษณะของ Run Time ได้แล้ว รวมไปถึงการนำข้อมูลต่างๆเข้าสู่ตารางกริดในแต่ละหลัก แต่ละแถว หากเป็นระบบฐานข้อมูล ก็สามารถทำ Query ดึงข้อมูลเข้าสู่ตารางกริดได้นั่นปะไรล่ะครับ

คราวนี้มาดูวิธีการคิด เพื่อเตรียมเข้าสู่กระบวนงานจริงๆ
การค้นหาข้อมูลในตารางกริด หากมีข้อมูลเดิมอยู่แล้ว ให้เพิ่มจำนวนสินค้าขึ้นอีก 1 รายการ หากไม่พบข้อมูลในตารางกริด ให้เพิ่มรายการ (แถว) เข้าไปใหม่ ... การนำไปใช้งานจริงๆ ก็คือการค้นหาข้อมูลรายการสินค้า ตามรหัสบาร์โค้ด เพื่อทำรายการขายยังไงล่ะครับ ... พี่น้อง ... เพียงแต่ผมไม่ได้โยงเรื่องของฐานข้อมูลมาเกี่ยวข้อง ให้ผู้เรียนสับสนเล่นเท่านั้นเอง

Design Time


Run Time

โค้ดที่ใช้นำทางให้ผู้เรียน เพื่อเตรียมเข้าสู่การเชื่อมความสัมพันธ์ของตารางแบบ One To Many

' ======================================================
' การเกิดเหตุการณ์ค้นหาข้อมูลรหัสสินค้า โดยการกดปุ่ม Enter
' ======================================================
Private Sub txtSearch_KeyPress(KeyAscii As Integer)
    If KeyAscii = vbKeyReturn Then
        Call CheckDataRow
    End If
End Sub

' ======================================================
' การตรวจสอบค่าใน MS FlexGrid ก่อนที่จะแสดงผลรายการใหม่
' ======================================================
Private Sub CheckDataRow()
    Dim CurrentRow As Integer

    ' ตรวจสอบว่าเป็นค่าว่างหรือไม่ หากใช่ก็ออกจากโปรแกรมย่อย (User ไม่มีการคีย์ข้อมูลใดๆ)
    If Trim(txtSearch.Text) = "" Or Len(Trim(txtSearch.Text)) = 0 Then
        txtSearch.SetFocus
        Exit Sub
    End If

    ' =========================================================
    ' เวลานำไปประยุกต์ใช้งานจริง ก็คือ ณ ตรงนี้คือการทำ Query ค้นหาจากฐานข้อมูลก่อน
    ' หากไม่พบข้อมูล (รหัสสินค้าที่ต้องการ) ก็ให้เด้งออกจากโปรแกรมย่อยนี้ไปเลย ...
    ' =========================================================
    
    ' เริ่มต้นการค้นหาข้อมูลในตารางกริด
    For CurrentRow = 1 To fgData.Rows - 1
        ' ค้นหารหัสสินค้าที่อยู่ในหลักที่ 1
        If fgData.TextMatrix(CurrentRow, 1) = Trim(txtSearch.Text) Then
            
            ' หากพบรายการสินค้าเดิมใส่จำนวนสินค้าเพิ่มเข้าไปอีก 1 ทันที ในแถวปัจจุบัน
            fgData.TextMatrix(CurrentRow, 3) = Val(fgData.TextMatrix(CurrentRow, 3)) + 1
            
            ' คูณราคาสินค้า กับจำนวนสินค้าเข้าไปใหม่
            fgData.TextMatrix(CurrentRow, 4) = Format(Val(fgData.TextMatrix(CurrentRow, 3)) * _
                            Val(fgData.TextMatrix(CurrentRow, 2)), "0.00")
                            
            ' เคลียร์ค่า
            txtSearch.Text = ""
            ' จบจากการวนรอบ FOR และ ออกจากโปรแกรมย่อยไปเลยครับ
            Exit Sub
        End If
    Next
    
    ' **************************** นี่คือ LOGIC ที่สำคัญ **************************
   ' เป็นระดับมือใหม่ รายไหนรายนั้น ที่ไม่รู้ว่าเจอ หรือ ไม่เจอ แล้วต้องทำอย่างไรดี
   ' *************************************************************************
    
    ' =================================================
    ' คำตอบก็คือ หากมันวนรอบแถวจนหมด แล้วออกมายังจุดนี้ได้ นั่นก็แสดงว่า
   ' มันยังไม่มีข้อมูลรหัสสินค้าอยู่ในรายการตารางกริดยังไงล่ะครับ ... พี่น้อง
   ' หากเวลาใช้งานจริง ก็คือการนำรายละเอียดของสินค้าเข้าสู่ตารางกริดนั่นเอง
    ' =================================================
    
    ' เพิ่มจำนวนแถวใน MS FlexGrid อีก 1 แถว
    fgData.Rows = fgData.Rows + 1
    
    ' ให้แถวปัจจุบันลดลง 1 (เพื่อไม่ให้นับ Column Header)
    CurrentRow = fgData.Rows - 1
    
    ' แถวใหม่ที่เพิ่มเข้ามา ทำการตั้งค่าข้อมูล (สมมุติ) ให้ดู ยกเว้นรหัสสินค้า
    Randomize
    ' ปกติหลักแรก (หลัก 0) ต้องนำเอาค่า Primary Key ไปซ่อนเอาไว้น่ะครับ ... อย่าลืม
    fgData.TextMatrix(CurrentRow, 0) = CurrentRow
    ' แสดงรหัสสินค้า
    fgData.TextMatrix(CurrentRow, 1) = Trim$(txtSearch.Text)
    ' แสดงราคาสินค้า
    fgData.TextMatrix(CurrentRow, 2) = Format(Int(10000 * Rnd), "0.00")
    ' ใส่จำนวนสินค้าครั้งละ 1
    fgData.TextMatrix(CurrentRow, 3) = 1
    fgData.TextMatrix(CurrentRow, 4) = Format(fgData.TextMatrix(CurrentRow, 2) * _
                                fgData.TextMatrix(CurrentRow, 3), "0.00")
    txtSearch.Text = ""
End Sub
Conclusion:
นี่คือขั้นตอนต่างๆในการสอน (ของผม) ที่ถ่ายทอดออกไปยังผู้เรียน ให้ได้เข้าใจถึงหลักการ แนวคิด และ เป็นพื้นฐานที่ต้องนำไปใช้ ก่อนที่ก้าวย่างต่อไปข้างหน้าได้ ด้วยรากฐานที่แข็งแรงพอ ... ไม่ใช่อยู่ดีๆ เอ้า ไปทำโปรแกรมรายการขายสินค้ามาส่งครูด้วย แหม !!! ไม่อยากขอบรรยายอะไรมากนัก สำหรับระบบการเรียนรู้ การศึกษาของไทยๆเรา ... พอมาถึงตรงนี้ ผมคิดว่าหลายต่อหลายคนคงพอมองเห็นหนทางสว่างไสว ในการพัฒนาโปรแกรมกันไปบ้างแล้วแหละครับ แต่ทั้งนี้ทั้งนั้น อยากฝากงานไปคิดเพิ่มเติม และ ผมอยากให้ลองไปดูส่วนอื่นๆที่ผมเขียนเอาไว้เกี่ยวกับ MS FlexGrid ... จะทำอย่างไรให้ใส่ราคาสินค้า จำนวน ส่วนลด ลงใน MS FlexGrid ได้เลย ... ง่ายๆ หมูๆ ... พอจากส่วนนี้ไปก็คงจะได้มาบรรยายถึงกระบวนการดึง และ จัดเก็บข้อมูล ในส่วนของ DataBase ต่อไปครับ