ชุมชนคนรักภาษาเบสิค - Visual Basic Community

 ลืมรหัสผ่าน
 ลงทะเบียน
ค้นหา
ดู: 12990|ตอบกลับ: 16

[VB.NET] พื้นฐานการเขียนโปรแกรมแบบ CRUD (Create, Read, Update, Delete) กับตัวอย่างฐานข้อมูลผู้ป่วย MS Access

[คัดลอกลิงก์]

308

กระทู้

498

โพสต์

5971

เครดิต

ผู้ดูแลระบบ

ทองก้อน ทับทิมกรอบ

Rank: 9Rank: 9Rank: 9

เครดิต
5971


ที่ต้องบอกว่าเป็นพื้นฐาน ก็เพราะว่าแอดมินจะใช้ตารางข้อมูลแบบเดี่ยวๆ โดยที่ไม่มีการสร้างความสัมพันธ์ใดๆระหว่างตารางข้อมูลเลย โดยจะเน้นแนวทางให้ศึกษาวิธีการ เพิ่มรายการใหม่ (Create) การอ่านหรือค้นคืน (Read/Retrieve) การปรับปรุง (Update) และการลบข้อมูล (Delete) ซึ่งเป็นพื้นฐานของการเขียนโปรแกรมเพื่อติดต่อกับฐานข้อมูล แต่โดยรวมๆการควบคุมโปรแกรม (Flow Control) จะเรียงลำดับขั้นตอนนี้ คือ
การค้นคืนข้อมูล จะมี 2 ลักษณะคือ
- หากไม่พบข้อข้อมูลที่ต้องการ ก็คือต้องไปทำการสร้างใหม่
- หากพบข้อมูล ก็จะมี 2 ทางเลือก คือ นำมาแก้ไข หรือ ลบข้อมูล

การออกแบบตารางข้อมูลอย่างง่าย

จบภาคทฤษฎีเล็กๆ ก็จะมาว่ากันเรื่องการปฏิบัติ โดยเน้นการลงมือทำ อันเป็นหัวใจสำคัญของการเรียนรู้ ...


โค้ดในการค้นคืนข้อมูล ...
  1.     ' / --------------------------------------------------------------------
  2.     ' / Data Retrieval
  3.     Private Sub RetrieveData(Optional ByVal blnSearch As Boolean = False)
  4.         If blnSearch Then
  5.             strSQL = _
  6.                 " SELECT Patient.HNPK, Patient.HN, Patient.PatientName, Patient.Address, Patient.Amphur, Patient.ProvinceName, Patient.PostCode, Patient.Telephone, Patient.BirthDate, Patient.Sex, Patient.Blood " & _
  7.                 " FROM(Patient) " & _
  8.                 " WHERE " & _
  9.                 " [HN] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  10.                 " [PatientName] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  11.                 " [Address] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  12.                 " [Amphur] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  13.                 " [ProvinceName] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  14.                 " [PostCode] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  15.                 " [Telephone] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  16.                 " [Sex] " & " Like '%" & txtSearch.Text & "%'" & " OR " & _
  17.                 " [Blood] " & " Like '%" & txtSearch.Text & "%'" & _
  18.                 " ORDER BY Patient.HN "
  19.         Else
  20.             strSQL = _
  21.                 " SELECT Patient.HNPK, Patient.HN, Patient.PatientName, Patient.Address, Patient.Amphur, Patient.ProvinceName, " & _
  22.                 " Patient.PostCode, Patient.Telephone, Patient.BirthDate, Patient.Sex, Patient.Blood " & _
  23.                 " FROM(Patient) ORDER BY Patient.HN "
  24.         End If
  25.         DA = New OleDb.OleDbDataAdapter(strSQL, Conn)
  26.         DS = New DataSet
  27.         DS.Clear()
  28.         DA.Fill(DS, "Patient")
  29.         dgvData.DataSource = DS.Tables("Patient")
  30.         lblRecordCount.Text = "[จำนวน : " & dgvData.RowCount & " รายการ]"
  31.         '//
  32.         DA.Dispose()
  33.         DS.Dispose()
  34.         Conn.Close()
  35.         '//
  36.         InitializeGrid()
  37.         txtSearch.Clear()
  38.     End Sub
คัดลอกไปที่คลิปบอร์ด
จากโปรแกรมย่อย RetrieveData(Optional ByVal blnSearch As Boolean = False) เป็นเทคนิคในการเขียนโค้ดที่สามารถค้นหาและนำข้อมูลมาแสดงผลได้ในโปรแกรมย่อยตัวเดียวกัน โดยการกำหนดว่า หาก blnSearch = False จะเป็นการแสดงผลข้อมูลทั้งหมด แต่ถ้าหาก blnSearch = True จะเป็นการค้นหาข้อมูล ซึ่งการค้นหาข้อมูลจะมาจากการป้อนค่าใน TextBox

โค้ดการค้นหาข้อมูลที่ป้อนลงใน TextBox
  1.     ' / --------------------------------------------------------------------
  2.     Private Sub txtSearch_KeyPress(sender As Object, e As System.Windows.Forms.KeyPressEventArgs) Handles txtSearch.KeyPress
  3.         '// ดักจับตัวอักขระอันไม่พึงปรารถนาสำหรับฐานข้อมูล เช่น ', * หรือ %
  4.         txtSearch.Text = Replace(Trim(txtSearch.Text), "'", "")
  5.         txtSearch.Text = Replace(Trim(txtSearch.Text), "%", "")
  6.         txtSearch.Text = Replace(Trim(txtSearch.Text), "*", "")
  7.         If Trim(txtSearch.Text) = "" Or Len(Trim(txtSearch.Text)) = 0 Then Exit Sub
  8.         '// SearchData(True) หมายความว่า เป็นการค้นหาข้อมูล
  9.         If e.KeyChar = Chr(13) Then '// Chr(13) คือ ASCII Code ของ Enter
  10.             '// ปิดเสียงเตือน
  11.             e.Handled = True
  12.             Call RetrieveData(True)
  13.         End If
  14.     End Sub
คัดลอกไปที่คลิปบอร์ด
RetrieveData(True) เพื่อระบุว่าเป็นการค้นหา

การเพิ่มข้อมูลใหม่ (Create)
โค้ดในส่วนของการสร้าง Primary Key เพื่อไม่ให้เกิดมีค่าที่ซ้ำกัน ... นิยามของ Primary Key หรือ PK คือกุญแจหลัก จะมีค่าที่ซ้ำกันไม่ได้ และเปลี่ยนแปลงค่าไม่ได้ การที่เปลี่ยนค่านี้ไม่ได้ ก็เพราะจะต้องนำคีย์หลักตัวนี้ไปเชื่อมต่อ หรือสร้างความสัมพันธ์เข้ากับตารางตัวอื่นๆ และที่สำคัญค่า PK เป็นค่าที่ผู้เขียนโปรแกรมจะต้องอ้างอิงไว้ใช้งาน
  1.     ' / --------------------------------------------------------------------
  2.     ' / ฟังค์ชั่นในการหาค่า Primary Key ตัวใหม่ไม่ให้ซ้ำกัน
  3.     Function SetupNewPK(ByVal sql As String) As Long
  4.         If Conn.State = ConnectionState.Closed Then Conn.Open()
  5.         Cmd = New OleDb.OleDbCommand(sql, Conn)
  6.         '/ ตรวจสอบว่ามีข้อมูลอยู่หรือไม่ และคืนค่ากลับ
  7.         If IsDBNull(Cmd.ExecuteScalar) Then
  8.             SetupNewPK = 1
  9.         Else
  10.             SetupNewPK = Cmd.ExecuteScalar + 1
  11.         End If
  12.     End Function
คัดลอกไปที่คลิปบอร์ด

โค้ดในส่วนของการสร้าง ID หรือ IDentfier โดยไม่ให้เกิดมีค่าที่ซ้ำกัน ... แอดมินขอแนะนำให้แยกนิยามความหมายของคำว่า Primary Key ออกไปจาก IDentifier ซึ่งในที่นี้ ID ก็คือ HN หรือ Hospital Number ของผู้ป่วย
  1.     ' / --------------------------------------------------------------------
  2.     ' / ฟังค์ชั่นในการสร้างรหัสลูกค้า หรือ ID แบบอัตโนมัติ ตามรูปแบบที่เราต้องการ
  3.     Function SetupAutoID() As String
  4.         strSQL = _
  5.             " SELECT MAX(Patient.HNPK) AS MaxPK FROM Patient "
  6.         If Conn.State = ConnectionState.Closed Then Conn.Open()
  7.         Cmd = New OleDb.OleDbCommand(strSQL, Conn)
  8.         Dim MaxPK As Long
  9.         '/ ตรวจสอบว่ามีข้อมูลอยู่หรือไม่
  10.         If IsDBNull(Cmd.ExecuteScalar) Then
  11.             MaxPK = 1
  12.         Else
  13.             MaxPK = Cmd.ExecuteScalar + 1
  14.         End If
  15.         '/ ตัวอย่างของการสร้างรูปแบบ ID อัตโนมัติ HN-ปีพ.ศ.XXXXX เช่น HN-6000013
  16.         '/ เช่น ได้ MaxPK = 13 เอามาเรียงต่อกันกับ 0 จำนวน 5 ตัว ก็จะได้ "00000" & "13" = "0000013"
  17.         '/ ให้นับกลับมาจากทางขวาเข้ามาทางซ้าย ก็จะได้ "00013"
  18.         SetupAutoID = "HN-" & Microsoft.VisualBasic.Right(Year(Now), 2) & Microsoft.VisualBasic.Right("00000" & MaxPK, 5)
  19.     End Function
คัดลอกไปที่คลิปบอร์ด

ฟังค์ชั่นในการตรวจสอบค่า ID (หรือ HN) ว่ามีค่าที่ซ้ำกันหรือไม่ ... นิยามของ IDentifier หรือ รหัสผู้ป่วย (HN) จะมีค่าที่ซ้ำกันไม่ได้ แต่สามารถเปลี่ยนแปลงค่าได้ การที่มันสามารถเปลี่ยนแปลงค่าได้ ก็เพราะอาจจะเกิดการป้อนข้อมูลที่ผิดพลาดของผู้ใช้งาน และค่า HN จะเป็นค่าที่ Users เขาอ้างอิงถึงเสมอ
  1.     ' / --------------------------------------------------------------------
  2.     ' / ฟังค์ชั่นในการหาค่า ID ซ้ำกัน
  3.     Public Function DuplicateID(ByVal Sql As String) As Boolean
  4.         If Conn.State = ConnectionState.Closed Then Conn.Open()
  5.         Cmd = New OleDb.OleDbCommand(Sql, Conn)
  6.         ' Return count records
  7.         DuplicateID = Cmd.ExecuteScalar
  8.     End Function
คัดลอกไปที่คลิปบอร์ด

เทคนิคในการดักตรวจสอบค่า HN เพื่อไม่ให้เกิดการซ้ำกันได้ สิ่งแรกคือต้องเก็บค่า HN ของเดิมเอาไว้ในตัวแปรตัวใดตัวหนึ่งก่อน แต่แอดมินใช้คุณสมบัติของ TextBox ที่มีชื่อว่า Tag เพื่อประหยัดตัวแปร ...
  1.             txtHN.Text = "" & .Rows(0)("HN").ToString()
  2.             '// เก็บค่า HN เดิมเอาไว้ เพื่อทำการเปรียบเทียบในภายหลัง
  3.             txtHN.Tag = txtHN.Text
คัดลอกไปที่คลิปบอร์ด
- กรณีที่เพิ่มข้อมูลใหม่ ค่าใน Tag = "" แต่ต้องนำค่าคุณสมบัติใน Text ของ TextBox ไปเปรียบเทียบกับของเดิมที่มีอยู่ในตารางข้อมูล
- กรณีที่ทำการแก้ไข จะแบ่งเป็น 2 กรณี คือ
---- ค่าใน Tag = Text นั่นหมายความว่า ไม่มีการแก้ไขค่า HN ก็ให้ทำการบันทึกข้อมูลได้ทันที
---- ค่าใน Tag <> Text แสดงว่ามีการเปลี่ยนแปลงค่า HN ก็จะต้องไปเปรียบเทียบกับของเดิมที่มีอยู่ในตารางข้อมูล
  1.         If txtHN.Text.ToLower <> LCase(txtHN.Tag) Then
  2.             strSQL = _
  3.                 " SELECT Count(Patient.HN) AS CountHN FROM Patient " & _
  4.                 " WHERE HN = " & "'" & txtHN.Text & "'"
  5.             If DuplicateID(strSQL) Then
  6.                 MessageBox.Show("HN มีค่าซ้ำ กรุณาแก้ไขใหม่ให้เรียบร้อยด้วย.", "รายงานความผิดพลาด", MessageBoxButtons.OK, MessageBoxIcon.Warning)
  7.                 txtHN.Focus()
  8.                 Exit Sub
  9.             End If
  10.         End If
คัดลอกไปที่คลิปบอร์ด

โค้ดในส่วนของการบันทึกข้อมูล ... สามารถกระทำได้ทั้งการเพิ่ม (Insert) หรือ การปรับปรุง (Update) ในโปรแกรมย่อยตัวเดียวกัน ก็เพราะแอดมินอาศัยตัวแปรแบบ Boolean ชื่อ NewData หากค่า NewData = True ก็คือการเพิ่มข้อมูลใหม่ หากเป็น False ก็คือการแก้ไข
  1.     ' / --------------------------------------------------------------------
  2.     ' / บันทึกข้อมูล
  3.     ' / --------------------------------------------------------------------
  4.     Private Sub SaveData()
  5.         If NewData Then
  6.             strSQL = _
  7.                 " INSERT INTO Patient(" & _
  8.                 " HNPK, HN, PatientName, Address, Amphur, ProvinceName, PostCode, Telephone, " & _
  9.                 " BirthDate, Sex, Blood, DateAdded, DateModified) " & _
  10.                 " VALUES('" & _
  11.                 SetupNewPK(" SELECT MAX(Patient.HNPK) AS MaxPK FROM Patient ") & "','" & _
  12.                 txtHN.Text & "','" & _
  13.                 txtPatientName.Text & "','" & _
  14.                 txtAddress.Text & "','" & _
  15.                 txtAmphur.Text & "','" & _
  16.                 txtProvinceName.Text & "','" & _
  17.                 txtPostCode.Text & "','" & _
  18.                 txtTelephone.Text & "','" & _
  19.                 dtpBirthDate.Value & "','" & _
  20.                 CheckSex() & "','" & _
  21.                 cmbBlood.Text & "','" & _
  22.                 Now & "','" & _
  23.                 Now & _
  24.                 "')"
  25.             '// EDIT MODE
  26.         Else
  27.             '// START UPDATE
  28.             strSQL = _
  29.                 " UPDATE Patient SET " & _
  30.                 " HN='" & txtHN.Text & "', " & _
  31.                 " PatientName='" & txtPatientName.Text & "', " & _
  32.                 " Address='" & txtAddress.Text & "', " & _
  33.                 " Amphur='" & txtAmphur.Text & "', " & _
  34.                 " ProvinceName='" & txtProvinceName.Text & "', " & _
  35.                 " PostCode='" & txtPostCode.Text & "', " & _
  36.                 " Telephone='" & txtTelephone.Text & "', " & _
  37.                 " BirthDate='" & dtpBirthDate.Value & "', " & _
  38.                 " Sex='" & CheckSex() & "', " & _
  39.                 " Blood='" & cmbBlood.Text & "', " & _
  40.                 " DateModified='" & Now & "'" & _
  41.                 " WHERE HNPK=" & PK & ""    ' ค่า PK จะได้มาจากการดับเบิ้ลคลิ๊กเลือกรายการแก้ไขเอาไว้แล้วล่วงหน้า
  42.         End If
  43.         '// การ Insert/Update กระทำเหมือนกัน
  44.         If DoSQL(strSQL) Then
  45.             MessageBox.Show("ปรับปรุงข้อมูลเรียบร้อย.", "รายงานสถานะ", MessageBoxButtons.OK, MessageBoxIcon.Information)
  46.         End If
  47.         '// แสดงข้อมูลในตารางกริดใหม่
  48.         RetrieveData()  '// Refresh
  49.         '// ตั้งค่าโหมด
  50.         NewMode()
  51.     End Sub
คัดลอกไปที่คลิปบอร์ด

แถมท้ายกับการเรียกข้อมูลมาแสดงผล ... แอดมินมีโค้ดอยู่ 2 ชุด เพื่อให้ศึกษาและเปรียบเทียบ โดยชุดจริงจะเป็นกรณีที่ใช้แบบ Multi-users ซึ่งจะต้องทำการ Query ข้อมูลเข้ามาใหม่ อีกชุดตามโค้ดด้านล่างจะเป็นแบบ Stand Alone โดยการเรียกข้อมูลมาแสดงผลจากตารางกริดแทน ซึ่งการเลือกไปใช้ในงานจริงๆ ก็อยู่ที่ว่าจะเป็นงานเล็กงานใหญ่กันล่ะครับ
  1.     ' / --------------------------------------------------------------------
  2.     ' / เรียกข้อมูลจาก DataGrid มาแสดงผล (กรณีใช้ Stand Alone)
  3.     ' / --------------------------------------------------------------------
  4.     Private Sub DataGridToScreen()
  5.         '//
  6.         Dim iRow As Integer
  7.         '// อ่านค่าแถวที่ถูกโฟกัส
  8.         iRow = dgvData.CurrentRow.Index
  9.         '//
  10.         PK = dgvData.Item(0, iRow).Value  '// เก็บค่า Primary Key เอาไว้
  11.         txtHN.Text = "" & dgvData.Item(1, iRow).Value
  12.         '// เก็บค่า HN เดิมเอาไว้ เพื่อทำการเปรียบเทียบในภายหลัง
  13.         txtHN.Tag = txtHN.Text
  14.         '// การใช้ Double quote "" เพื่อดักค่าว่าง (แนวคิดดั้งเดิมมาตั้งแต่ VB6)
  15.         txtPatientName.Text = "" & dgvData.Item(2, iRow).Value
  16.         txtAddress.Text = "" & dgvData.Item(3, iRow).Value
  17.         txtAmphur.Text = "" & dgvData.Item(4, iRow).Value
  18.         txtProvinceName.Text = "" & dgvData.Item(5, iRow).Value
  19.         txtPostCode.Text = "" & dgvData.Item(6, iRow).Value
  20.         txtTelephone.Text = "" & dgvData.Item(7, iRow).Value
  21.         '//
  22.         dtpBirthDate.Value = dgvData.Item(8, iRow).Value
  23.         lblAge.Text = CalcDate(dtpBirthDate.Value, Now)
  24.         '//
  25.         If dgvData.Item(9, iRow).Value = "ชาย" Then
  26.             rbtSexM.Checked = True
  27.         Else
  28.             rbtSexF.Checked = True
  29.         End If
  30.         cmbBlood.Text = dgvData.Item(10, iRow).Value
  31.     End Sub
คัดลอกไปที่คลิปบอร์ด
Conclusion: แอดมินก็หวังว่า คงจะเป็นแนวทางให้ได้เรียนรู้ศึกษากระบวนการขั้นตอนต่างๆ เพื่อให้ทุกๆท่านที่ได้เผลอเข้ามาอ่านกัน ได้รับความรู้ไปบ้างไม่เล็กก็น้อยก็ใหญ่ก็มากครับผม ... อนึ่ง!!! การได้เห็นโค้ด แต่ถ้าหากไม่ลองนำไปปฏิบัติจริง หรือคิดเพิ่มเติม ก็คงจะไม่มีประโยชน์อะไร ... สวัสดี

ดาวน์โหลดโค้ดต้นฉบับแบบเต็ม VB.NET (2010) ได้ที่นี่

ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง

คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน

x
สิ่งที่ดีกว่าการให้ คือการให้แบบไม่มีที่สิ้นสุด

0

กระทู้

1

โพสต์

19

เครดิต

Newbie

Rank: 1

เครดิต
19
โพสต์ 2018-9-14 22:02:35 | ดูโพสต์ทั้งหมด

ดีมากเลยครับ แบ่งปันความรู้...
ขออนุญาตนำไปศึกษาและประยุกต์ใช้นะครับอาจารย์
ขอบพระคุณมากๆครับ

1

กระทู้

15

โพสต์

83

เครดิต

Member

Rank: 2

เครดิต
83
โพสต์ 2018-9-24 09:55:16 | ดูโพสต์ทั้งหมด

ค่อยจีบเมียใหม่ครับเฮีย

0

กระทู้

1

โพสต์

16

เครดิต

Newbie

Rank: 1

เครดิต
16
โพสต์ 2018-9-24 11:29:09 | ดูโพสต์ทั้งหมด

ขอบคุณครับ
ขออนุญาตินำไปศึกษาและพัฒนานะครับ

1

กระทู้

11

โพสต์

81

เครดิต

Member

Rank: 2

เครดิต
81
โพสต์ 2019-2-16 14:40:15 | ดูโพสต์ทั้งหมด

ขอบพระคุณคะ

0

กระทู้

5

โพสต์

132

เครดิต

Member

Rank: 2

เครดิต
132
โพสต์ 2019-7-15 10:57:11 | ดูโพสต์ทั้งหมด

ขอบคุณครับ

0

กระทู้

2

โพสต์

6

เครดิต

Newbie

Rank: 1

เครดิต
6
โพสต์ 2019-10-26 21:22:04 | ดูโพสต์ทั้งหมด

ขอบคุณครับ

4

กระทู้

13

โพสต์

102

เครดิต

Member

Rank: 2

เครดิต
102
โพสต์ 2019-11-12 22:04:01 | ดูโพสต์ทั้งหมด

ขอบคุณครับ อาจารย์

0

กระทู้

1

โพสต์

6

เครดิต

Newbie

Rank: 1

เครดิต
6
โพสต์ 2019-12-1 20:04:05 | ดูโพสต์ทั้งหมด

ขอบคุณค่ะ

0

กระทู้

13

โพสต์

40

เครดิต

Newbie

Rank: 1

เครดิต
40
โพสต์ 2019-12-9 09:20:34 | ดูโพสต์ทั้งหมด

ขอบคุรครับ
ขออภัย! คุณไม่ได้รับสิทธิ์ในการดำเนินการในส่วนนี้ กรุณาเลือกอย่างใดอย่างหนึ่ง ลงชื่อเข้าใช้ | ลงทะเบียน

รายละเอียดเครดิต

ข้อความล้วน|อุปกรณ์พกพา|ประวัติการแบน|G2GNet.com  

GMT+7, 2024-3-28 15:51 , Processed in 0.228778 second(s), 4 queries , File On.

Powered by Discuz! X3.4, Rev.62

Copyright © 2001-2020 Tencent Cloud.

ตอบกระทู้ ขึ้นไปด้านบน ไปที่หน้ารายการกระทู้