Option Explicit
' #####################################################
' เริ่มต้นการแสดงรายละเอียดของลูกค้า ตามค่า Primary Key จากฟอร์มหลัก
' #####################################################
Private Sub Form_Load()
' รับค่า CustomerPK ที่เราซ่อนเอาไว้ จากหลักแรก (Index = 0) มาจากฟอร์มหลัก
' ก่อนจะมาถึงฟอร์มนี้ เรากำหนดให้อ่านหลัก 0 ของ DataGrid มาก่อนแล้วล่วงหน้า
' หากเอาแบบให้แน่ใจก็กำหนดใหม่ได้ โดยการอ้างถึงฟอร์มหลักโดยตรง
frmDataControlRetrieve.DataGrid1.Col = 0
CustomerPrimaryKey = frmDataControlRetrieve.DataGrid1.Text
' ส่วนนี้จริงๆแล้ว ต้องแยกออกเป็นโปรแกรมย่อย เพราะต้องมีการทดสอบก่อนว่าเป็นการเพิ่ม หรือ แก้ไขข้อมูล
' หากเป็นการเพิ่มข้อมูลใหม่ ก็จะเคลียร์ค่า Control ต่างๆเพื่อเริ่มต้นการป้อนข้อมูลใหม่
' หากเป็นการแก้ไข ก็จะต้องทำการแสดงผลข้อมูลเดิมขึ้นมา ... นี่แหละคือการออกแบบเป็นขั้นเป็นตอน
' ทำ Query เพื่อทำการค้นหาข้อมูล
Statement = "SELECT * FROM tblCustomer " & _
" WHERE " & _
" [CustomerPK] = " & CustomerPrimaryKey & _
" ORDER BY CustomerPK "
' หากมีนับเป็นสิบๆฟอร์มก็ต้องมาทำ Connection กันใหม่ในทุกๆฟอร์มกันล่ะครับ
' Adodc1 ในฟอร์มหลัก กับในฟอร์มนี้มันคนละตัวกัน ทำให้ต้องทำการ Connect ใหม่
' มันเป็นการ Connect เข้าหาไฟล์ก้อนเดียวกัน จึงทำให้เปลืองหน่วยความจำ
' และ อาจจะเกิดอันตรายต่อไฟล์ฐานข้อมูลได้ด้วย ... ยิ่งเป็นระบบ LAN หลับตานึกภาพเอาเองเลยครับ
With Adodc1
.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0; " & _
" Data Source=" & App.Path & "\MyDB.MDB; " & _
" Persist Security Info=False"
' ผูกข้อมูลตาม Query ที่กำหนดให้กับ ADO Data Control ใหม่อีกครั้ง
.RecordSource = Statement
' สั่งทำงานตามคำสั่ง SQL (Query) ... กรณีที่ Design Time ไม่ได้ตั้งค่าเอาไว้ล่วงหน้า
.CommandType = adCmdText
' สามารถอ่านจำนวน Record ได้ ... ไปกำหนดตอน Design Time เอาก็ได้ครั้งเดียว
.CursorLocation = adUseClient
' อ่านเดินหน้าอย่างเดียว กรณีของการแสดงผล
.LockType = adLockReadOnly
' ปรับข้อมูลใหม่ใน Adodc1
.Refresh
' นำเอาข้อมูลจากการ Query เพื่อทำการแสดงผลข้อมูล
txtCustomerCode.Text = Adodc1.Recordset("CustomerCode")
txtCustomerName.Text = Adodc1.Recordset("CustomerName")
txtAddress.Text = Adodc1.Recordset("Address")
txtAmphur.Text = Adodc1.Recordset("Amphur")
txtPostCode.Text = Adodc1.Recordset("PostCode")
End With
' ความจริงต้องประกาศตัวแปรต่างๆ เอาไว้บนสุดของ Sub Program น่ะครับ ... จะได้ไม่สับสน
' ประกาศตัวแปรเพื่อรับค่ารายชื่อจังหวัดเอาไว้ก่อน แล้วค่อยนำไปเทียบรายการใน DataCombo
Dim ProvinceName As String
ProvinceName = Adodc1.Recordset("ProvinceName")
Adodc1.Recordset.Close
' #####################################################
' หากในฟอร์มมี ComboBox นับ 10 ตัวล่ะ จะมี ADO Data Control ทั้ง 10 ตัวเลยเหรอ
' ส่วนนี้คือการนำ Adodc1 กลับมาใช้งานอีกรอบ แต่เปลี่ยน RecordeSource ใหม่
' เพื่อ Query หารายชื่อจังหวัด นำมาแสดงผลลงใน DataCombo เสียก่อน
' #####################################################
Statement = "SELECT * FROM tblProvince ORDER BY ProvinceName "
With Adodc1
.CursorLocation = adUseClient
.CommandType = adCmdText
.RecordSource = Statement
.Refresh
End With
Set DataCombo1.RowSource = Adodc1
DataCombo1.ListField = "ProvinceName"
' นำค่า ProvinceName จากการ Query เดิมมาเทียบใส่กับ DataCombo
DataCombo1.Text = ProvinceName
' #####################################################
End Sub
' #####################################################
' เกิดเหตุการณ์กดปุ่ม (Event) ... สั่งทำ Driven คือ
' - ตรวจสอบการป้อนข้อมูล
' - บันทึกผลเข้าสู่ตารางข้อมูล
' - กลับไปรายการหลัก
' #####################################################
Private Sub cmdSave_Click()
' การตรวจสอบค่าว่างในฟิลด์ที่สำคัญๆ และจำเป็น เช่น รหัสลูกค้า ชื่อลูกค้า
' ผมจะข้ามการทดสอบหารหัสลูกค้าที่ซ้ำกันออกไป ... สามารถดูรายละเอียดเพิ่มเติมได้จาก
' http://www.g2gnet.com/News ... หรือ เอาไปคิดเป็นการบ้านเองด้วยครับ
If Trim(txtCustomerCode.Text) = "" Then
MsgBox "กรุณาป้อนรหัสลูกค้าให้เรียบร้อยก่อนด้วย.", vbOKOnly + vbExclamation, "รายงานสถานะ"
txtCustomerCode.SetFocus
Exit Sub
ElseIf Trim(txtCustomerName.Text) = "" Then
MsgBox "กรุณาป้อนชื่อลูกค้าให้เรียบร้อยก่อนด้วย.", vbOKOnly + vbExclamation, "รายงานสถานะ"
txtCustomerName.SetFocus
Exit Sub
End If
' #####################################################
' สั่งบันทึกข้อมูล ... ส่วนนี้ควรแยกออกเป็นโปรแกรมย่อย ... จะดีกว่า
' #####################################################
' ความจริงต้องประกาศตัวแปรต่างๆ เอาไว้บนสุดของ Sub Program น่ะครับ ... จะได้ไม่สับสน
' เนื่องเราใช้ ADO Data Control เพียงแค่ตัวเดียว ดังนั้นจะต้องไปหาค่า Primary Key
' ของรายชื่อจังหวัดที่เลือกเข้ามาก่อน ... นั่นคือการจัดเรียงลำดับเหตุการณ์เพื่อไม่ให้เกิดข้อผิดพลาด
Dim ProvincePrimaryKey As Integer
ProvincePrimaryKey = CompareProvinceName
Statement = "SELECT tblCustomer.CustomerPK, tblCustomer.CustomerCode, " & _
" tblCustomer.CustomerName, tblCustomer.Address, tblCustomer.Amphur, " & _
" tblCustomer.ProvinceFK, tblProvince.ProvinceName, tblCustomer.PostCode " & _
" FROM tblCustomer INNER JOIN tblProvince ON " & _
" tblCustomer.ProvinceFK = tblProvince.ProvincePK " & _
" WHERE " & _
" [CustomerPK] = " & CustomerPrimaryKey & _
" ORDER BY CustomerPK "
With Adodc1
.RecordSource = Statement
' ต้องใช้ adCmdText แทน เพราะเราใช้ SQL Statement ไม่ได้ใช้ตาราง (adCmdTable)
' หากกำหนดเป็น adCmdTable จะเกิด Syntax error in FROM clause
.CommandType = adCmdText
.CursorLocation = adUseClient
' เมื่อต้องการบันทึกผล หรือ เขียนข้อมูลลงไปในตารางข้อมูล ต้องปรับใหม่
.CursorType = adOpenKeyset
.LockType = adLockOptimistic
.Refresh
.Recordset.Fields("CustomerCode") = "" & txtCustomerCode.Text
.Recordset.Fields("CustomerName") = "" & txtCustomerName.Text
.Recordset.Fields("Address") = "" & txtAddress.Text
.Recordset.Fields("Amphur") = "" & txtAmphur.Text
.Recordset.Fields("ProvinceFK") = ProvincePrimaryKey
.Recordset.Fields("PostCode") = "" & txtPostCode.Text
' บันทึกข้อมูลใหม่ (Update)
.Recordset.Update
' ปิดการเชื่อมต่อกับตารางข้อมูล
.Recordset.Close
End With
MsgBox "บันทึกข้อมูลเรียบร้อย.", vbOKOnly + vbInformation, "รายงานสถานะ"
' ปิดฟอร์มกลับไปที่โปรแกรมรายการหลัก
Unload Me
End Sub
' #####################################################
' เนื่องจากต้องมีการส่งค่า Primary Key ของจังหวัดนั้นๆ กลับคืนไปเราจึงต้องใช้ฟังค์ชั่นแทน
' แต่ไม่มีการรับค่าเข้ามา นำค่า Text ที่อยู่ใน DataCombo มาทดสอบหาค่า Primary Key
' #####################################################
Function CompareProvinceName() As Integer
Statement = "SELECT tblProvince.ProvincePK, tblProvince.ProvinceName " & _
" FROM tblProvince " & _
" WHERE ProvinceName = " & "'" & DataCombo1.Text & "'"
With Adodc1
.RecordSource = Statement
.CommandType = adCmdText
.CursorLocation = adUseClient
.LockType = adLockReadOnly
.Refresh
End With
' ส่งค่าคืนกลับ (แบบเลขจำนวนเต็ม) โดยใช้ชื่อฟังค์ชั่นของตัวมันเอง
CompareProvinceName = Adodc1.Recordset("ProvincePK")
' ปิดการเชื่อมต่อกับตารางข้อมูล
Adodc1.Recordset.Close
End Function
|