ลงชื่อเข้าใช้
กระดานข่าว VB
>
เว็บบอร์ดเปิดโค้ดต้นฉบับ
ส่ง
|
[VB.NET] พื้นฐานการเขียนโปรแกรมแบบ CRUD (Create, Read, Update, Delete) กับตัวอย่างฐานข้อมูลผู้ป่วย MS Access
ดู12991
|
โพสต์17
|
บุ๊คมาร์ก
thongkorn
ดูทั้งหมด
2017-11-4 12:25:08
ที่ต้องบอกว่าเป็นพื้นฐาน ก็เพราะว่าแอดมินจะใช้ตารางข้อมูลแบบเดี่ยวๆ
โดยที่ไม่มีการสร้างความสัมพันธ์ใดๆระหว่างตารางข้อมูลเลย โดยจะเน้นแนวทางให้ศึกษาวิธีการ เพิ่มรายการใหม่ (
Create
) การอ่านหรือค้นคืน (
Read/Retrieve
) การปรับปรุง (
Update
) และการลบข้อมูล (
Delete
) ซึ่งเป็นพื้นฐานของการเขียนโปรแกรมเพื่อติดต่อกับฐานข้อมูล แต่โดยรวมๆการควบคุมโปรแกรม (Flow Control) จะเรียงลำดับขั้นตอนนี้ คือ
การค้นคืนข้อมูล
จะมี 2 ลักษณะคือ
- หากไม่พบข้อข้อมูลที่ต้องการ ก็คือต้องไปทำการสร้างใหม่
- หากพบข้อมูล ก็จะมี 2 ทางเลือก คือ นำมาแก้ไข หรือ ลบข้อมูล
การออกแบบตารางข้อมูลอย่างง่าย
จบภาคทฤษฎีเล็กๆ ก็จะมาว่ากันเรื่องการปฏิบัติ โดยเน้นการลงมือทำ อันเป็นหัวใจสำคัญของการเรียนรู้ ...
โค้ดในการค้นคืนข้อมูล
...
โค้ด:
' / --------------------------------------------------------------------
' / Data Retrieval
Private Sub RetrieveData(Optional ByVal blnSearch As Boolean = False)
If blnSearch Then
strSQL = _
" SELECT Patient.HNPK, Patient.HN, Patient.PatientName, Patient.Address, Patient.Amphur, Patient.ProvinceName, Patient.PostCode, Patient.Telephone, Patient.BirthDate, Patient.Sex, Patient.Blood " & _
" FROM(Patient) " & _
" WHERE " & _
" [HN] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [PatientName] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [Address] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [Amphur] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [ProvinceName] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [PostCode] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [Telephone] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [Sex] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
" [Blood] " & " Like '%" & txtSearch.Text & "%'" & _
" ORDER BY Patient.HN "
Else
strSQL = _
" SELECT Patient.HNPK, Patient.HN, Patient.PatientName, Patient.Address, Patient.Amphur, Patient.ProvinceName, " & _
" Patient.PostCode, Patient.Telephone, Patient.BirthDate, Patient.Sex, Patient.Blood " & _
" FROM(Patient) ORDER BY Patient.HN "
End If
DA = New OleDb.OleDbDataAdapter(strSQL, Conn)
DS = New DataSet
DS.Clear()
DA.Fill(DS, "Patient")
dgvData.DataSource = DS.Tables("Patient")
lblRecordCount.Text = "[จำนวน : " & dgvData.RowCount & " รายการ]"
'//
DA.Dispose()
DS.Dispose()
Conn.Close()
'//
InitializeGrid()
txtSearch.Clear()
End Sub
จากโปรแกรมย่อย RetrieveData(
Optional ByVal blnSearch As Boolean = False
) เป็นเทคนิคในการเขียนโค้ดที่สามารถค้นหาและนำข้อมูลมาแสดงผลได้ในโปรแกรมย่อยตัวเดียวกัน โดยการกำหนดว่า หาก blnSearch = False จะเป็นการแสดงผลข้อมูลทั้งหมด แต่ถ้าหาก blnSearch = True จะเป็นการค้นหาข้อมูล ซึ่งการค้นหาข้อมูลจะมาจากการป้อนค่าใน TextBox
โค้ดการค้นหาข้อมูลที่ป้อนลงใน TextBox
โค้ด:
' / --------------------------------------------------------------------
Private Sub txtSearch_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtSearch.KeyPress
'// ดักจับตัวอักขระอันไม่พึงปรารถนาสำหรับฐานข้อมูล เช่น ', * หรือ %
txtSearch.Text = Replace(Trim(txtSearch.Text), "'", "")
txtSearch.Text = Replace(Trim(txtSearch.Text), "%", "")
txtSearch.Text = Replace(Trim(txtSearch.Text), "*", "")
If Trim(txtSearch.Text) = "" Or Len(Trim(txtSearch.Text)) = 0 Then Exit Sub
'// SearchData(True) หมายความว่า เป็นการค้นหาข้อมูล
If e.KeyChar = Chr(13) Then '// Chr(13) คือ ASCII Code ของ Enter
'// ปิดเสียงเตือน
e.Handled = True
Call RetrieveData(True)
End If
End Sub
RetrieveData(
True
) เพื่อระบุว่าเป็นการค้นหา
การเพิ่มข้อมูลใหม่ (Create)
โค้ดในส่วนของการสร้าง
Primary Key
เพื่อไม่ให้เกิดมีค่าที่ซ้ำกัน
... นิยามของ Primary Key หรือ PK คือกุญแจหลัก จะมีค่าที่ซ้ำกันไม่ได้ และเปลี่ยนแปลงค่าไม่ได้ การที่เปลี่ยนค่านี้ไม่ได้ ก็เพราะจะต้องนำคีย์หลักตัวนี้ไปเชื่อมต่อ หรือสร้างความสัมพันธ์เข้ากับตารางตัวอื่นๆ และที่สำคัญค่า PK เป็นค่าที่ผู้เขียนโปรแกรมจะต้องอ้างอิงไว้ใช้งาน
โค้ด:
' / --------------------------------------------------------------------
' / ฟังค์ชั่นในการหาค่า Primary Key ตัวใหม่ไม่ให้ซ้ำกัน
Function SetupNewPK(ByVal sql As String) As Long
If Conn.State = ConnectionState.Closed Then Conn.Open()
Cmd = New OleDb.OleDbCommand(sql, Conn)
'/ ตรวจสอบว่ามีข้อมูลอยู่หรือไม่ และคืนค่ากลับ
If IsDBNull(Cmd.ExecuteScalar) Then
SetupNewPK = 1
Else
SetupNewPK = Cmd.ExecuteScalar + 1
End If
End Function
โค้ดในส่วนของการสร้าง ID หรือ IDentfier โดยไม่ให้เกิดมีค่าที่ซ้ำกัน
... แอดมินขอแนะนำให้แยกนิยามความหมายของคำว่า Primary Key ออกไปจาก IDentifier ซึ่งในที่นี้
ID ก็คือ HN
หรือ Hospital Number ของผู้ป่วย
โค้ด:
' / --------------------------------------------------------------------
' / ฟังค์ชั่นในการสร้างรหัสลูกค้า หรือ ID แบบอัตโนมัติ ตามรูปแบบที่เราต้องการ
Function SetupAutoID() As String
strSQL = _
" SELECT MAX(Patient.HNPK) AS MaxPK FROM Patient "
If Conn.State = ConnectionState.Closed Then Conn.Open()
Cmd = New OleDb.OleDbCommand(strSQL, Conn)
Dim MaxPK As Long
'/ ตรวจสอบว่ามีข้อมูลอยู่หรือไม่
If IsDBNull(Cmd.ExecuteScalar) Then
MaxPK = 1
Else
MaxPK = Cmd.ExecuteScalar + 1
End If
'/ ตัวอย่างของการสร้างรูปแบบ ID อัตโนมัติ HN-ปีพ.ศ.XXXXX เช่น HN-6000013
'/ เช่น ได้ MaxPK = 13 เอามาเรียงต่อกันกับ 0 จำนวน 5 ตัว ก็จะได้ "00000" & "13" = "0000013"
'/ ให้นับกลับมาจากทางขวาเข้ามาทางซ้าย ก็จะได้ "00013"
SetupAutoID = "HN-" & Microsoft.VisualBasic.Right(Year(Now), 2) & Microsoft.VisualBasic.Right("00000" & MaxPK, 5)
End Function
ฟังค์ชั่นในการตรวจสอบค่า ID (หรือ HN) ว่ามีค่าที่ซ้ำกันหรือไม่
... นิยามของ IDentifier หรือ รหัสผู้ป่วย (HN) จะมีค่าที่ซ้ำกันไม่ได้ แต่สามารถเปลี่ยนแปลงค่าได้ การที่มันสามารถเปลี่ยนแปลงค่าได้ ก็เพราะอาจจะเกิดการป้อนข้อมูลที่ผิดพลาดของผู้ใช้งาน และค่า HN จะเป็นค่าที่ Users เขาอ้างอิงถึงเสมอ
โค้ด:
' / --------------------------------------------------------------------
' / ฟังค์ชั่นในการหาค่า ID ซ้ำกัน
Public Function DuplicateID(ByVal Sql As String) As Boolean
If Conn.State = ConnectionState.Closed Then Conn.Open()
Cmd = New OleDb.OleDbCommand(Sql, Conn)
' Return count records
DuplicateID = Cmd.ExecuteScalar
End Function
เทคนิคในการดักตรวจสอบค่า HN เพื่อไม่ให้เกิดการซ้ำกันได้
สิ่งแรกคือต้องเก็บค่า HN ของเดิมเอาไว้ในตัวแปรตัวใดตัวหนึ่งก่อน แต่แอดมินใช้คุณสมบัติของ TextBox ที่มีชื่อว่า Tag เพื่อประหยัดตัวแปร ...
โค้ด:
txtHN.Text = "" & .Rows(0)("HN").ToString()
'// เก็บค่า HN เดิมเอาไว้ เพื่อทำการเปรียบเทียบในภายหลัง
txtHN.Tag = txtHN.Text
- กรณีที่เพิ่มข้อมูลใหม่
ค่าใน Tag = "" แต่ต้องนำค่าคุณสมบัติใน Text ของ TextBox ไปเปรียบเทียบกับของเดิมที่มีอยู่ในตารางข้อมูล
- กรณีที่ทำการแก้ไข
จะแบ่งเป็น 2 กรณี คือ
----
ค่าใน Tag = Text
นั่นหมายความว่า ไม่มีการแก้ไขค่า HN ก็ให้ทำการบันทึกข้อมูลได้ทันที
----
ค่าใน Tag <> Text
แสดงว่ามีการเปลี่ยนแปลงค่า HN ก็จะต้อง
ไปเปรียบเทียบกับของเดิมที่มีอยู่ในตารางข้อมูล
โค้ด:
If txtHN.Text.ToLower <> LCase(txtHN.Tag) Then
strSQL = _
" SELECT Count(Patient.HN) AS CountHN FROM Patient " & _
" WHERE HN = " & "'" & txtHN.Text & "'"
If DuplicateID(strSQL) Then
MessageBox.Show("HN มีค่าซ้ำ กรุณาแก้ไขใหม่ให้เรียบร้อยด้วย.", "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Warning)
txtHN.Focus()
Exit Sub
End If
End If
โค้ดในส่วนของการบันทึกข้อมูล
... สามารถกระทำได้ทั้งการเพิ่ม (Insert) หรือ การปรับปรุง (Update) ในโปรแกรมย่อยตัวเดียวกัน ก็เพราะแอดมินอาศัยตัวแปรแบบ Boolean ชื่อ
NewData
หากค่า NewData = True ก็คือการเพิ่มข้อมูลใหม่ หากเป็น False ก็คือการแก้ไข
โค้ด:
' / --------------------------------------------------------------------
' / บันทึกข้อมูล
' / --------------------------------------------------------------------
Private Sub SaveData()
If NewData Then
strSQL = _
" INSERT INTO Patient(" & _
" HNPK, HN, PatientName, Address, Amphur, ProvinceName, PostCode, Telephone, " & _
" BirthDate, Sex, Blood, DateAdded, DateModified) " & _
" VALUES('" & _
SetupNewPK(" SELECT MAX(Patient.HNPK) AS MaxPK FROM Patient ") & "','" & _
txtHN.Text & "','" & _
txtPatientName.Text & "','" & _
txtAddress.Text & "','" & _
txtAmphur.Text & "','" & _
txtProvinceName.Text & "','" & _
txtPostCode.Text & "','" & _
txtTelephone.Text & "','" & _
dtpBirthDate.Value & "','" & _
CheckSex() & "','" & _
cmbBlood.Text & "','" & _
Now & "','" & _
Now & _
"')"
'// EDIT MODE
Else
'// START UPDATE
strSQL = _
" UPDATE Patient SET " & _
" HN='" & txtHN.Text & "', " & _
" PatientName='" & txtPatientName.Text & "', " & _
" Address='" & txtAddress.Text & "', " & _
" Amphur='" & txtAmphur.Text & "', " & _
" ProvinceName='" & txtProvinceName.Text & "', " & _
" PostCode='" & txtPostCode.Text & "', " & _
" Telephone='" & txtTelephone.Text & "', " & _
" BirthDate='" & dtpBirthDate.Value & "', " & _
" Sex='" & CheckSex() & "', " & _
" Blood='" & cmbBlood.Text & "', " & _
" DateModified='" & Now & "'" & _
" WHERE HNPK=" & PK & "" ' ค่า PK จะได้มาจากการดับเบิ้ลคลิ๊กเลือกรายการแก้ไขเอาไว้แล้วล่วงหน้า
End If
'// การ Insert/Update กระทำเหมือนกัน
If DoSQL(strSQL) Then
MessageBox.Show("ปรับปรุงข้อมูลเรียบร้อย.", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Information)
End If
'// แสดงข้อมูลในตารางกริดใหม่
RetrieveData() '// Refresh
'// ตั้งค่าโหมด
NewMode()
End Sub
แถมท้ายกับการเรียกข้อมูลมาแสดงผล
... แอดมินมีโค้ดอยู่ 2 ชุด เพื่อให้ศึกษาและเปรียบเทียบ โดยชุดจริงจะเป็นกรณีที่ใช้แบบ Multi-users ซึ่งจะต้องทำการ Query ข้อมูลเข้ามาใหม่ อีกชุดตามโค้ดด้านล่างจะเป็นแบบ Stand Alone โดยการเรียกข้อมูลมาแสดงผลจากตารางกริดแทน ซึ่งการเลือกไปใช้ในงานจริงๆ ก็อยู่ที่ว่าจะเป็นงานเล็กงานใหญ่กันล่ะครับ
โค้ด:
' / --------------------------------------------------------------------
' / เรียกข้อมูลจาก DataGrid มาแสดงผล (กรณีใช้ Stand Alone)
' / --------------------------------------------------------------------
Private Sub DataGridToScreen()
'//
Dim iRow As Integer
'// อ่านค่าแถวที่ถูกโฟกัส
iRow = dgvData.CurrentRow.Index
'//
PK = dgvData.Item(0, iRow).Value '// เก็บค่า Primary Key เอาไว้
txtHN.Text = "" & dgvData.Item(1, iRow).Value
'// เก็บค่า HN เดิมเอาไว้ เพื่อทำการเปรียบเทียบในภายหลัง
txtHN.Tag = txtHN.Text
'// การใช้ Double quote "" เพื่อดักค่าว่าง (แนวคิดดั้งเดิมมาตั้งแต่ VB6)
txtPatientName.Text = "" & dgvData.Item(2, iRow).Value
txtAddress.Text = "" & dgvData.Item(3, iRow).Value
txtAmphur.Text = "" & dgvData.Item(4, iRow).Value
txtProvinceName.Text = "" & dgvData.Item(5, iRow).Value
txtPostCode.Text = "" & dgvData.Item(6, iRow).Value
txtTelephone.Text = "" & dgvData.Item(7, iRow).Value
'//
dtpBirthDate.Value = dgvData.Item(8, iRow).Value
lblAge.Text = CalcDate(dtpBirthDate.Value, Now)
'//
If dgvData.Item(9, iRow).Value = "ชาย" Then
rbtSexM.Checked = True
Else
rbtSexF.Checked = True
End If
cmbBlood.Text = dgvData.Item(10, iRow).Value
End Sub
Conclusion:
แอดมินก็หวังว่า คงจะเป็นแนวทางให้ได้เรียนรู้ศึกษากระบวนการขั้นตอนต่างๆ เพื่อให้ทุกๆท่านที่ได้เผลอเข้ามาอ่านกัน ได้รับความรู้ไปบ้างไม่เล็กก็น้อยก็ใหญ่ก็มากครับผม ... อนึ่ง!!! การได้เห็นโค้ด แต่ถ้าหากไม่ลองนำไปปฏิบัติจริง หรือคิดเพิ่มเติม ก็คงจะไม่มีประโยชน์อะไร ... สวัสดี
ดาวน์โหลดโค้ดต้นฉบับแบบเต็ม VB.NET (2010) ได้ที่นี่
ไฟล์แนบ:
คุณจำเป็นต้อง
ลงชื่อเข้าใช้
ก่อนจึงจะสามารถดูและดาวน์โหลดไฟล์แนบได้ หากยังไม่มีบัญชีหรือยังไม่ได้เป็นสมาชิก กรุณา
ลงทะเบียน
Khim
ดูทั้งหมด
2018-9-14 22:02:35
ดีมากเลยครับ แบ่งปันความรู้...
ขออนุญาตนำไปศึกษาและประยุกต์ใช้นะครับอาจารย์
ขอบพระคุณมากๆครับ
hot2
ดูทั้งหมด
2018-9-24 09:55:16
ค่อยจีบเมียใหม่ครับเฮีย
Phuvanart
ดูทั้งหมด
2018-9-24 11:29:09
ขอบคุณครับ
ขออนุญาตินำไปศึกษาและพัฒนานะครับ
prawpun
ดูทั้งหมด
2019-2-16 14:40:15
ขอบพระคุณคะ
yusanc
ดูทั้งหมด
2019-7-15 10:57:11
ขอบคุณครับ
mukitti
ดูทั้งหมด
2019-10-26 21:22:04
ขอบคุณครับ
komen
ดูทั้งหมด
2019-11-12 22:04:01
ขอบคุณครับ อาจารย์
TanadpornPeadee
ดูทั้งหมด
2019-12-1 20:04:05
ขอบคุณค่ะ
jaricha5
ดูทั้งหมด
2019-12-9 09:20:34
ขอบคุรครับ
1
2
/ 2 หน้า
ถัดไป
G2GNet.com
Powered by
Discuz!
X3.4
โฮมเพจ
|
รูปแบบทั่วไป
|
รูปแบบโมเดิร์น
|
รูปแบบคอมพิวเตอร์