Option Explicit
' #####################################################
' ประกาศตัวแปรที่เห็นได้หมดในฟอร์มนี้ ... เพราะต้องนำไปใช้ซ้ำๆกัน ในหลายๆโปรแกรมย่อย
' ซึ่งเราจะประกาศ (Declare) มันครั้งเดียวก็เพียงพอแล้วขอรับ ...
' #####################################################
' ตัวแปรเพื่อเก็บค่า String ในการทำ SQL Statement
Dim Statement As String
' ตัวแปรเพื่อรับค่า CustomerPK เข้ามาจากฟอร์มหลัก (DataGrid)
' เพราะต้องนำค่านี้ไปใช้งานตอน ...
' 1. แสดงผลข้อมูล (อยู่ที่ Form_Load)
' 2. บันทึกข้อมูล (ในโปรแกรมย่อย SaveData) อีกด้วย
' ความจริงแล้ว สำหรับค่า Primary Key เราอ้างถึงฟอร์มหลักที่เรียกมาก็ได้
' เช่น frmDataControlRetrieve.DataGrid1.Text
' แต่ที่ผมแยกให้เห็น เพื่อจะได้ไม่งง ... เลยตั้งชื่อมันซ่ะเต็มยศเลย 55555+
' ที่จริงแล้วผมมีเทคนิคที่ผมใช้อีกแบบ ... กลับไปหาดูในบทความเก่าๆของผมด้วยล่ะกันครับ
Dim CustomerPrimaryKey As Long
' #####################################################
' เริ่มต้นการแสดงรายละเอียดของลูกค้า ตามค่า Primary Key จากฟอร์มหลัก
' #####################################################
Private Sub Form_Load()
' รับค่า CustomerPK ที่เราซ่อนเอาไว้ จากหลักแรก (Index = 0) มาจากฟอร์มหลัก
' ก่อนจะมาถึงฟอร์มนี้ เรากำหนดให้อ่านหลัก 0 ของ DataGrid มาก่อนแล้วล่วงหน้า
' หากเอาแบบให้แน่ใจก็กำหนดใหม่ได้ โดยการอ้างถึงฟอร์มหลักโดยตรง
frmDataControlRetrieve.DataGrid1.Col = 0
CustomerPrimaryKey = frmDataControlRetrieve.DataGrid1.Text
' ส่วนนี้จริงๆแล้ว ต้องแยกออกเป็นโปรแกรมย่อย เพราะต้องมีการทดสอบก่อนว่าเป็นการเพิ่ม หรือ แก้ไขข้อมูล
' หากเป็นการเพิ่มข้อมูลใหม่ ก็จะเคลียร์ค่า Control ต่างๆเพื่อเริ่มต้นการป้อนข้อมูลใหม่
' หากเป็นการแก้ไข ก็จะต้องทำการแสดงผลข้อมูลเดิมขึ้นมา ... นี่แหละคือการออกแบบเป็นขั้นเป็นตอน
' ทำ Query เพื่อทำการค้นหาข้อมูล
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
' ผูกข้อมูลตาม 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
' นำค่า ProvinceName จาก Adodc1 ไปให้กับ DataCombo
' รับรองว่าไม่มีพลาดครับ ... หากเราเชื่อมความสัมพันธ์ และ กำหนดข้อมูลระหว่าง 2 ตารางได้ถูกต้อง
DataCombo1.Text = Adodc1.Recordset("ProvinceName")
Adodc1.Recordset.Close
' ไม่สามารถปิด Adodc2.Recordset.Close ... เพราะต้องผูกเข้ากับ DataCombo อยู่
' #####################################################
' พอเริ่มจะเซียนขึ้นมา ก็ต้องพัฒนาการเขียนโค้ดแบบ Run Time ประหยัด ADO Data Control
' ส่วนนี้คือการนำ Adodc1 กลับมาใช้งานอีกรอบ แต่เปลี่ยน RecordeSource ใหม่
' เพื่อ Query หารายชื่อจังหวัด นำมาแสดงผลลงใน DataCombo เสียก่อน
' ซึ่งผมจะนำมาใช้งานในตอนหน้าน่ะครับ ... ตอนนี้ก็ลองคิดเล่นๆไปพลางๆก่อนก็แล้วกัน
' #####################################################
'Statement = "SELECT tblCustomer.ProvinceFK, tblProvince.ProvinceName " & _
" FROM tblProvince INNER JOIN tblCustomer ON " & _
" tblProvince.ProvincePK = tblCustomer.ProvinceFK " & _
" WHERE ProvinceName = " & "'" & ProvinceName & "'"
'If Adodc1.Recordset.State <> 0 Then Adodc1.Recordset.Close
'Adodc1.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" & _
" Data Source=" & App.Path & "\MyDB.mdb;" & _
" Persist Security Info=False"
'Adodc1.CursorLocation = adUseClient
'Adodc1.CommandType = adCmdText
'Adodc1.RecordSource = Statement
'Adodc1.Refresh
'Set DataCombo1.DataSource = Adodc1
'DataCombo1.DataField = "ProvinceName"
' ก่อนถึงบรรทัดคำสั่งนี้ ต้องเก็บค่า ProvinceName จากการ Query การแสดงผลตัวแรกก่อน
'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
' #####################################################
' สั่งบันทึกข้อมูล ... ส่วนนี้ควรแยกออกเป็นโปรแกรมย่อย จะดีกว่า
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
' ต้องไปทำงานโปรแกรมย่อย CompareProvinceName เพื่อตรวจสอบค่าใน DataCombo
' ว่าตรงกับ Primary Key อะไร ... เพราะในตารางลูกค้า เราจะเก็บเฉพาะค่า ProvinceFK
.Recordset.Fields("ProvinceFK") = CompareProvinceName
.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 Adodc2
.RecordSource = Statement
.CommandType = adCmdText
.CursorLocation = adUseClient
.LockType = adLockReadOnly
.Refresh
End With
' ส่งค่าคืนกลับ (แบบเลขจำนวนเต็ม) โดยใช้ชื่อฟังค์ชั่นของตัวมันเอง
CompareProvinceName = Adodc2.Recordset("ProvincePK")
' ปิดการเชื่อมต่อกับตารางข้อมูล
Adodc2.Recordset.Close
End Function
' #####################################################
' ก่อนปิดหน้าจอ ต้องตัดการการเชื่อมต่อไฟล์ฐานข้อมูลด้วย
' #####################################################
Private Sub Form_Unload(Cancel As Integer)
If Adodc1.Recordset.ActiveConnection.State = adStateOpen Then
Adodc1.Recordset.ActiveConnection.Close
Set Adodc1.Recordset.ActiveConnection = Nothing
End If
If Adodc2.Recordset.ActiveConnection.State = adStateOpen Then
Adodc2.Recordset.ActiveConnection.Close
Set Adodc2.Recordset.ActiveConnection = Nothing
End If
End Sub
Private Sub cmdExit_Click()
Unload Me
End Sub
|