หากมีคำถาม ขอให้ไปโพสต์ลง เว็บบอร์ดจีทูจีเน็ตดอตคอม ตัวใหม่แทนน่ะครับ

หรือติดต่อเข้ามาทาง Inbox ที่ เฟซบุ๊ค ผมครับ

หน้าหลัก
ข่าวสาร - บทความ ทั้งหมด
VB 6/VB.Net
ASP/ASP.Net
จับฉ่ายคอมพิวเตอร์
เรียนรู้ผ่าน Flash Movie
บทความที่มีผู้ตอบล่าสุด  
 RSS Feeds
 ดาวน์โหลดโปรแกรม RSS Reader ได้ที่นี่ ...   Download โปรแกรม RSS Reader

Forum - www.g2gnet.com
Webmaster - www.g2gnet.com
Visitors - Session views
 5 2 9 0 9 3 1

7 ธันวาคม พ.ศ.2549
378 Users On-Line.
Visitors - Page views
 8 6 2 1 5 5 2
1 กุมภาพันธ์ พ.ศ.2551

Google   
เว็บ g2gnet.com
ขนาดตัวอักษร:  

เรียนรู้ Visual Basic 6.0 กับ ฐานข้อมูล MS Access ภาค 9 (RadioTvOnline - DataBase)

Category »  VB 6/VB.Net
โดย : Webmaster เมื่อ 26/6/2550 13:01:00
(อ่าน : 18678) 

Start & Run ด้วยการสร้างโปรเจคขึ้นมาใหม่ ...


เลือก Project --> Components ... --> Windows Media Player

ลากวัตถุ (Component) เข้าสู่ฟอร์ม

จากตารางคุณสมบัติ (Properties) ก็ใส่ค่า URL ให้กับ Windows Media Player

จากนั้นกด F5 เพื่อรันโปรแกรม ... แค่นี้เองแบบว่าไม่ต้องเขียนโค้ดขึ้นมาเลยสักกะบรรทัด เราก็สามารถที่จะฟังวิทยุ หรือ ดูทีวีออนไลน์ได้แล้วแบบชิวๆ ... จบแล้วครับ

 

ผมมีความเชื่ออยู่อย่างหนึ่งก็คือ การเรียนรู้เพื่อที่จะพัฒนาโปรแกรมให้ได้ดีนั้น สิ่งแรกเลยก็คือการสร้าง "จินตนาการ" ขึ้นมาก่อน ซึ่งสิ่งนี้มันเป็นอะไรที่ล่องลอยอยู่กลางอากาศ (แหงนหน้ามองฟ้าด้วยครับ) และมันเป็นอะไรที่จับต้องไม่ได้ด้วย จากสิ่งที่อยู่ในอากาศนี้เราก็พยายามนำมันมาร่างแบบลงบนกระดาษเสียก่อน หรือที่เรียกว่า "การออกแบบ" นั่นเอง ซึ่งเราอาจจะสามารถเข้าใจมันได้เพียงคนเดียว จากแบบแผนที่ร่างลงกระดาษนั้น มันจะประกอบไปด้วย "ตรรกศาสตร์ หรือ Logic" ซึ่งเป็นเงื่อนไขที่สำคัญในการที่จะนำมันมาปั้นเป็นหน้าตาต่างๆให้ปรากฏอยู่บนหน้าจอภาพ และก็กลายสภาพมาเป็นโปรแกรม หรือ Application ให้เรา (หรือคนอื่นๆ) ลูบๆคลำๆได้นั่นไงล่ะครับ ... พี่น้อง

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



เลือก Coponent เข้ามา 2 ตัว


ตารางฐานข้อมูล ... แบบง่ายๆ
ดาวน์โหลด 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 จ้า ... พี่น้อง

ผลจากการรันโปรแกรม

เนื่องจากต้องใช้ฐานข้อมูลด้วยก็อย่าลืม ... Project --> References --> Microsoft ActiveX Data Object 2.X Library เข้ามาด้วยน่ะครับผม


' จากฟอร์มหลักตัวที่เป็นสาระสำคัญก็แค่กำหนด URL ให้กับ Windows Media Player เท่านั้นเอง
Private Sub cmdPlay_Click()
    If Trim(txtStation.Text) = "" Or Len(Trim(txtStation.Text)) = 0 Then Exit Sub
    WMP.URL = Trim(txtStation.Text)
End Sub

การเก็บข้อมูลอย่างง่ายๆเข้าใจได้ไม่ยาก ... ช่วยแก้ไขให้มันดูดีสวยงามหน่อยแล้วกันครับ ... พี่น้อง


' ฟอร์มรอง
Option Explicit
' ตัวแปรรับค่าจากตารางกริด (MS FlexGrid)
Dim StationID As Long
Dim StationName As String
Dim StationURL As String

Private Sub cmdExit_Click()
    Unload Me
End Sub

Private Sub cmdSave_Click()
If Trim(txtStationName.Text) = "" Or Len(txtStationName.Text) = 0 Then
    MsgBox "กรุณาป้อนข้อมูลรายชื่อสถานีให้เรียบร้อยก่อนด้วย.", vbOKOnly + vbExclamation, "รายงานสถานะ"
    txtStationName.SetFocus
    Exit Sub
ElseIf Trim(txtStationURL.Text) = "" Or Len(txtStationURL.Text) = 0 Then
    MsgBox "กรุณาป้อนข้อมูลตำแหน่ง URL ให้เรียบร้อยก่อนด้วย.", vbOKOnly + vbExclamation, "รายงานสถานะ"
    txtStationURL.SetFocus
    Exit Sub
End If
' เมื่อตรวจสอบข้อมูลเรียบร้อยก็เริ่มทำการบันทึกข้อมูล
Call SaveData
End Sub

Sub SaveData()
Dim CountRec As Long
Set RS = New ADODB.Recordset
    ' ตรวจสอบว่าเป็นการเพิ่มข้อมูลใหม่หรือไม่
    If blnNewData Then
        ' การกำหนดค่าให้กับ Primary Key (ค่าที่ไม่ซ้ำกัน) ไว้เพื่อเป็นตัวอ้างอิงถึงในการใช้งาน
        ' และการออกแบบฐานข้อมูลไม่ได้กำหนดให้ฟิลด์นี้เป็น AutoNumber
        ' ทำไม ? ... เพราะในอนาคตเราสามารถย้ายไปใช้งานในฐานข้อมูลตัวอื่นได้โดยไม่ต้องเปลี่ยนแปลงโค้ดใดๆ
        ' ถ้าหากฐานข้อมูลตัวนั้นมันไม่สนับสนุน AutoNumber จะทำอย่างไรล่ะครับ ... พี่น้อง
        ' และต้องบังคับให้เรียงตาม Primary Key คือ StationID
        ' ไม่เช่นนั้นอาจเกิดข้อผิดพลาด คือ สร้าง Primary Key ซ้ำกันได้
        Statement = "SELECT * FROM Station ORDER BY StationID "
        RS.CursorLocation = adUseClient
        ' สั่งให้อ่านไปข้างหน้าอย่างเดียว มันจะทำงานได้เร็วกว่า
        RS.Open Statement, ConnMyDB, adOpenForwardOnly, adLockReadOnly, adCmdText
        If RS.BOF Or RS.EOF Then
            CountRec = 1
        Else
            ' ย้ายตำแหน่งการชี้ข้อมูลไปเรคคอร์ดท้ายสุด แล้วให้เพิ่มขึ้น 1
            ' ผมไม่ใช้วิธีการนับ เพราะค่าที่ได้ค่าสุดท้ายจะไม่ตรงกับที่เราต้องการ
            RS.MoveLast
            CountRec = RS("StationID") + 1
        End If
        ' ปิดซ่ะ
        RS.Close
        '
        ' แล้วนำมันมาใช้งานใหม่
        Set RS = New ADODB.Recordset
        Statement = "SELECT * FROM Station ORDER BY StationID "
        RS.Open Statement, ConnMyDB, adOpenKeyset, adLockOptimistic, adCmdText
        ' เพิ่มข้อมูลใหม่ ก็คือใส่ค่า Primary Key เข้าไปก่อน
        RS.AddNew
        RS("StationID") = CountRec
    
    ' นั่นคือเป็นการแก้ไข เพราะ blnNewData = False
    Else
        Statement = "SELECT * FROM Station " & _
                                " WHERE [StationID] = " & StationID
        RS.Open Statement, ConnMyDB, adOpenKeyset, adLockOptimistic, adCmdText
    
    End If
    ' Technique ของการบันทึกข้อมูล ... ผมยังใช้อยู่จวบจนปัจจุบันนี้
    ' เพราะมันคือกระบวนการที่ทำงานซ้ำ ไม่ว่าจะเป็นกรณีของการเพิ่ม หรือ แก้ไขข้อมูล
    RS("StationName") = "" & Trim(txtStationName.Text)
    RS("StationURL") = "" & Trim(txtStationURL.Text)
    RS.Update
    MsgBox "บันทึกข้อมูลเรียบร้อย", vbOKOnly + vbInformation, "รายงานสถานะ"
    RS.Close
    Set RS = Nothing
    '
    ' การตั้งค่าให้เป็นโปรแกรมย่อย (Sub หรือ Function) จะช่วยลดโค้ดไปได้อีกโข
    ' กระบวนการต่างๆเหล่านี้ คุณจะเห็นชัดเจนเมื่อคุณร่างแบบการทำงานของโปรแกรมไว้ล่วงหน้า
    ' เมื่อเกิดเหตุการณ์ (Event) ... จะมีการขับเคลื่อน (Driven) หรือ ตอบสนองไปในทิศทางใด
    ' นี่คือ แนวคิดของ Visual Basic ครับ ... พี่น้อง
    
    ' เมื่อเกิดการบันทึกข้อมูลเรียบร้อย ก็ทำการเคลียร์หน้าจอใหม่
    ' นี่ก็ทำซ้ำอีกแล้ว ... เบื่อมั้ย ... ช่วยจัดการให้เป็นโปรแกรมย่อยน่ะครับ พี่น้อง
    Call SetupScreen
    Call SetupFgStation
    Call DisplayFgStation
    cmdSave.Enabled = False
    cmdSelect.Enabled = False
End Sub

Private Sub cmdSelect_Click()
    ' ดักความผิดพลาดกรณีที่ไม่มีข้อมูล
    ' StationID นี้จะมีค่าเกิดขึ้นมา เมื่อมีเหตุการณ์ก่อนหน้านี้
    ' นั่นคือ ... ตอนที่เรากดดับเบิ้ลคลิ๊กที่ FlexGrid ไงเล่าครับ พี่น้อง
    ' พยายามทำความเข้าใจกับหลักการ Event/Driven ให้ถ่องแท้ด้วยน่ะครับ
    If StationID <= 0 Then Exit Sub
    ' เลือกส่งค่าไปยังเป้าหมายคือ Object หรือ วัตถุ ในที่นี้คือ ฟอร์มหลัก
    ' ส่งค่านี้ไปให้ฟอร์มหลัก เพื่อแสดงผลบน Title Bar
    frmMainRadioTvOnline.Caption = "สถานี: " & StationName
    
    ' ค่าที่ส่งไปนี้เป็นการระบุ URL สถานีให้กับ WMP
    frmMainRadioTvOnline.txtStation.Text = StationURL
    
    ' ปิดหน้าจอไปซ่ะ
    Unload Me
    ' โปรดสังเกตุว่าทุกๆครั้งที่มีการเปิดตารางข้อมูล (RecordSet) ผมก็จะปิดมันเสมอ
    ' ทำให้ก่อนปิดฟอร์มเราจึงไม่ต้องมาคอยดัก คอยปิด RecordSet ต่างๆเลย
End Sub

Private Sub Form_Load()
    'Me.Move (Screen.Width - Width) \ 2, (Screen.Height - Height) \ 2
    txtSearch.Text = ""
    ' =============== เหตุการณ์ทำซ้ำ =============
    Call SetupScreen
    Call SetupFgStation
    Call DisplayFgStation
    '
    ' ปิดการทำงานของปุ่มไว้ก่อน
    cmdSave.Enabled = False
    cmdSelect.Enabled = False
    ' =======================================
    
    ' กระบวนการต่อจากนี้ไป จะเป็น Event/Driven
    ' คุณเลือกอะไร แล้วคุณจะให้มันทำอะไร ....
End Sub

' การนำข้อมูลจาก MS FlexGrid มาแสดงผลใน TextBox
' ความจริงแล้วคุณไม่ต้องส่งค่าใดๆมาให้ก็ได้ครับ เพราะตัวแปร StationID ที่เราประกาศไว้
' มันมองเห็นกันทั่วทั้งฟอร์มนี้หมดแล้ว ... แต่ผมอยากให้มือใหม่ทั้งหลาย
' ลองฝึกการส่งค่า และ รับค่าคืนกลับ (กรณี Function) ซึ่งในกรณีการใช้งานจริงเราต้องคอย Trap Error
' On Eror GoTo ... ซึ่งไม่ได้ง่ายๆแบบนี้เลยน่ะครับ ... พี่น้อง
Sub RecordToScreen(ID As Long)
Set RS = New Recordset
Statement = "SELECT * FROM Station " & _
                        " WHERE [StationID] = " & ID

    RS.Open Statement, ConnMyDB, adOpenForwardOnly, , adCmdText
    
    txtStationName.Text = "" & RS("StationName")
    txtStationURL.Text = "" & RS("StationURL")
    '
    ' ปิดตาราง
    RS.Close
    Set RS = Nothing
End Sub>

Private Sub Form_Unload(Cancel As Integer)
    Unload Me
End Sub

Sub SetupScreen()
    txtStationName.Text = ""
    txtStationURL.Text = ""
End Sub

Private Sub cmdDelete_Click()
    ' ดักความผิดพลาดก่อนเสมอ
    ' และตรวจสอบจาก TextMatrix ไม่ได้ดักผ่านจาก Col เหมือนตัวอย่างที่ผ่านมาครับ
    If Val(fgStation.TextMatrix(fgStation.Row, 0)) <= 0 Or _
        IsNull(fgStation.TextMatrix(fgStation.Row, 0)) Then Exit Sub
    '
    Statement = "DELETE * FROM Station WHERE [StationID] = " & Val(fgStation.Text)
    If MsgBox("คุณแน่ใจว่าต้องการลบข้อมูลสถานี " & fgStation.TextMatrix(fgStation.Row, 2) & " นี้?", _
                        vbOKCancel + vbQuestion + vbDefaultButton2, "ยืนยันการลบข้อมูล") = vbCancel Then
        Exit Sub
    End If
    Set RS = ConnMyDB.Execute(Statement)
    MsgBox "ลบข้อมูลสถานี " & fgStation.TextMatrix(fgStation.Row, 2) & " ออกจากระบบเรียบร้อยแล้ว.", _
                    vbOKOnly + vbInformation, "รายงานสถานะ"
    '
    ' กลับสู่สภาวะตั้งต้นใหม่ ... กระบวนการ (Routine) นี้มันซ้ำๆ กรุณาแก้เป็นโปรแกรมย่อยจะดีกว่า ... เน้อ พี่น้อง
    ' มันไม่ต่างอะไรกับงาน Routine ซ้ำๆกันทุกๆวันของเหล่าบรรดามนุษย์เงินเดือนนี่แหละ
    ' แล้วเราจะเอาคอมพิวเตอร์มาช่วยแก้ไข ทำให้งานซ้ำซากประจำวันนั้น
    ' ให้มันดีขึ้น เร็วขึ้น ประหยัดเวลาขึ้นได้อย่างไร ... นี่คือคำถามที่ผมฝากไว้ ... คอมพิวเตอร์+ชีวิตจริง
    Call SetupScreen
    Call SetupFgStation
    Call DisplayFgStation
    '
    cmdSave.Enabled = False
    cmdSelect.Enabled = False
End Sub

Private Sub cmdNew_Click()
    ' blnNewData เป็นตัวแปรแบบ Global ที่ผมเคยประกาศไว้ใน Module
    ' กรณีนี้เราสามารถประกาศไว้ในฟอร์มตัวมันเองก็ได้ครับ
    ' แต่เชื่อผมเหอะ ... กรณีที่คุณมีฟอร์มหลายๆฟอร์ม คุณจำเป็นต้องกำหนดให้มันเป็น Global นั่นแหละดีอยู่แล้ว
    
    ' เป็นการเพิ่มข้อมูล
    blnNewData = True
    ' เคลียร์หน้าจอ
    Call SetupScreen
    cmdSave.Enabled = True
    cmdSelect.Enabled = False
    txtStationName.SetFocus
End Sub

Private Sub cmdRefresh_Click()
    txtSearch.Text = ""
    Call SetupFgStation
    Call DisplayFgStation
End Sub

' การแก้ไขข้อมูล
Private Sub cmdEdit_Click()
    Call fgStation_DblClick
End Sub


' ตั้งค่าเริ่มต้น (Initialize) ให้กับ MS FlexGrid
Sub SetupFgStation()
    With fgStation
        .Clear
        .FixedRows = 1
        .FixedCols = 0
        .SelectionMode = flexSelectionByRow
        
        .Cols = 4
        .Rows = 1
        .TextMatrix(0, 0) = "StationID"
        .TextMatrix(0, 1) = "ลำดับที่"
        .TextMatrix(0, 2) = "ชื่อสถานี"
        .TextMatrix(0, 3) = ""
        
        .ColAlignment(2) = vbLeftJustify
        
        ' ปกติเราจะใช้ระยะความกว้างของวัตถุเป็นตัวคำนวณหาน่ะครับ
        ' กรณีที่คุณทำฟอร์มให้สามารถ Resize ได้
        .ColWidth(0) = 0
        .ColWidth(1) = 600
        .ColWidth(2) = .Width - .ColWidth(0) - .ColWidth(1) - 360
        .ColWidth(3) = 0    ' ซ่อน URL
    End With
End Sub


' แสดงผลค่าต่างๆใน MS FlexGrid
Sub DisplayFgStation()
Dim item As Long

Set RS = New Recordset
Statement = "SELECT *  FROM Station ORDER BY StationID "
RS.CursorLocation = adUseClient
RS.Open Statement, ConnMyDB, adOpenForwardOnly, adLockReadOnly, adCmdText
If RS.RecordCount <= 0 Then
    MsgBox "ยังไม่มีข้อมูลอยู่ในระบบ.", vbOKOnly + vbExclamation, "รายงานสถานะ"
    RS.Close
    Set RS = Nothing
    Exit Sub
End If


' นับจำนวนแถวทั้งหมดแล้วบวก 1 เพราะมันมี Header อยู่อีก 1 แถวไงครับ ... พี่น้อง
fgStation.Rows = RS.RecordCount + 1
RS.MoveFirst
item = 1
Do Until RS.EOF
    With fgStation
        .TextMatrix(item, 0) = RS("StationID")
        .TextMatrix(item, 1) = item
        .TextMatrix(item, 2) = "" & RS("StationName")
        .TextMatrix(item, 3) = "" & RS("StationURL")
    End With
    item = item + 1
    RS.MoveNext
Loop
' ปิดทุกครั้งที่เลิกใช้งาน
RS.Close
Set RS = Nothing
End Sub


' ค้นหาข้อมูล ... ส่วนนี้เราสามารถนำไปใช้กับโปรแกรมย่อย DisplayFgStation แทนได้ด้วยน่ะครับ
' ลองคิดเอาเอง ...
Private Sub cmdSearch_Click()
If txtSearch.Text = "" Or Len(Trim(txtSearch.Text)) = 0 Then
    txtSearch.SetFocus
    Exit Sub
End If

Dim item As Long
Set RS = New ADODB.Recordset
Statement = "SELECT * FROM Station " & _
                        " WHERE " & _
                            " [StationName] " & " Like '%" & Trim(txtSearch.Text) & "%'" & " OR " & _
                            " [StationURL] " & " Like '%" & Trim(txtSearch.Text) & "%'" & _
                            " ORDER BY StationID "

RS.CursorLocation = adUseClient
RS.Open Statement, ConnMyDB, adOpenForwardOnly, adLockReadOnly, adCmdText
' ตัวอย่างก่อนนี้ผมใช้ตัวแปรแทนเพื่อรับค่าน่ะครับ
If RS.RecordCount <= 0 Then
    MsgBox "ไม่พบข้อมูลที่คุณต้องการค้นหา.", vbOKOnly + vbExclamation, "รายงานสถานะ"
    RS.Close
    Set RS = Nothing
    Exit Sub
End If

fgStation.Rows = RS.RecordCount + 1
RS.MoveFirst
item = 1
Do Until RS.EOF
    With fgStation
        .TextMatrix(item, 0) = RS("StationID")
        .TextMatrix(item, 1) = item
        .TextMatrix(item, 2) = "" & RS("StationName")
        .TextMatrix(item, 3) = "" & RS("StationURL")
    End With
    item = item + 1
    RS.MoveNext
Loop

RS.Close
Set RS = Nothing
End Sub


' เหตุการณ์เมื่อดับเบิ้ลคลิ๊กที่ MS FlexGrid แล้วต้องนำข้อมูลมาแสดงผลใน TextBox
Private Sub fgStation_DblClick()
    ' ให้มั่นใจว่าชี้ไปที่ Column 0 ที่เราซ่อน Primary Key เอาไว้
    If Val(fgStation.TextMatrix(fgStation.Row, 0)) <= 0 Or _
            IsNull(fgStation.TextMatrix(fgStation.Row, 0)) Then Exit Sub
    
    ' เป็นการแก้ไขข้อมูล
    blnNewData = False
    '
    StationID = Val(fgStation.Text)
    StationName = fgStation.TextMatrix(fgStation.Row, 2)
    StationURL = fgStation.TextMatrix(fgStation.Row, 3)
    '
    ' นำข้อมูลมาแสดงผล โดยอ้างถึง Primary Key (StationID)
    Call RecordToScreen(StationID)
    '
    cmdSave.Enabled = True
    cmdSelect.Enabled = True
    txtStationName.SetFocus

End Sub

Private Sub fgStation_KeyPress(KeyAscii As Integer)
    If KeyAscii = vbKeyReturn Then Call fgStation_DblClick
End Sub

Conclusion: คุณคิดว่าได้รับอะไรจากบทความตอนนี้บ้างล่ะครับ ... หรือยังคิดไม่ออกอีกล่ะเนี่ย ... เหอๆๆๆๆ ... หากเป็นอย่างนี้ผมก็ไม่มีคำบรรยายอะไรเพิ่มเติมหรอกครับ ... พี่น้อง


จี ทู จี เน็ต ดอต คอม - g2gNet Dot Com
เลขทะเบียนพาณิชย์อิเล็กทรอนิกส์ 0407314800231
CopyLeft © 2004 - 2099 g2gNet.Com All rights reserved.
Email: [email protected] หรือ โทร. 08-6862-6560