|
จากโปรเจค แจกฟรีโค้ดโปรแกรมการเก็บบันทึกข้อมูลบุคคล โดยใช้ VB.NET + MS Access 2007+ เรามาดูในส่วนย่อยของการใช้ ComboBox ก็เพื่อเชื่อมความสัมพันธ์กันแบบ One to One ซึ่งโค้ดในบทความนี้จะเป็นต้นฉบับ ก่อนที่จะทำให้มันกลายไปเป็นโปรแกรมย่อย หรือฟังค์ชั่นเพื่อในงานจริง เพราะถ้าหากเราใช้ ComboBox เพียงตัวเดียวก็ไม่มีปัญหา แต่ทีนี้งานมันมีมากกว่า 1 ตัวนี่ซิ ... โดยตัวอย่างนี้จะใช้ตาราง tblPosition หรือแสดงตำแหน่งพนักงาน คำว่า One To One หมายความว่าพนักงาน 1 คน จะมีตำแหน่งได้เพียง 1 ตำแหน่งเท่านั้น (ในทางปฏิบัติจริงอาจจะมีมากกว่า 1 ตำแหน่งได้ แต่ตอนนี้เอาแบบพื้นฐานเบื้องต้นก่อนข่ะรับ) ...
ขออารัมภบทเล็กน้อย ในการออกแบบตารางข้อมูลตาม ทฤษฎีบทของทองก้อน (Thongkorn's Theorem) หากฟิลด์ข้อมูลใดมีค่าที่ซ้ำๆกันในตารางนั้น ให้แยกฟิลด์นั้นออกไปอยู่อีก 1 ตาราง จากนั้นจับมันกลับเข้ามาเชื่อมความสัมพันธ์กันใหม่อีกครั้ง จะปรากฏดังรูป
ที่เรียกว่า ความสัมพันธ์แบบ 1 ต่อ 1 ก็เพราะค่า PositionFK ในตารางหลัก tblContact จะมีความสัมพันธ์กับ PositionPK ในตารางย่อย tblPosition เพียงค่า 1 ค่า เช่น PositionFK และ PositionPK = 14 มันมีค่า PositionName = IT Specialist และค่าตำแหน่งนี้ก็จะมีอยู่ด้วยกัน 2 คน แต่ค่า "IT Specialist" มันจะเก็บค่าเอาไว้เพียง 1 ค่าเท่านั้นในตาราง tblPosition ... การแยกย่อยตารางออกไป ก็เพื่อลดความซ้ำซ้อนของข้อมูล และทำให้ลดขนาดของไฟล์ฐานข้อมูล (DataBase) ลงไปด้วยนั่นเอง ประเด็นที่สำคัญคือ มันเกิดความยืดหยุ่น อำนวยความสะดวกให้กับผู้ใช้งาน แต่ทั้งนี้ทั้งนั้นมันก็ต้องมาพร้อมกับการเขียนโปรแกรมที่ยากขึ้นไปอีกนั่นเอง ...
มาดูโค้ดในส่วนของการโหลดข้อมูลเข้าสู่ ComboBox
- ' / --------------------------------------------------------------------------------
- ' / Load Position data into ComboBox
- Private Sub PopulateComboBox()
- strSQL = "SELECT * FROM tblPosition ORDER BY PositionName "
- '// Initialize ComboBox
- With cmbPositionName
- .DropDownStyle = ComboBoxStyle.DropDown
- .AutoCompleteMode = AutoCompleteMode.Suggest
- .AutoCompleteSource = AutoCompleteSource.ListItems
- End With
- '//
- Try
- If Conn.State = ConnectionState.Closed Then Conn.Open()
- Cmd = New OleDb.OleDbCommand(strSQL, Conn)
- Dim DR As OleDb.OleDbDataReader = Cmd.ExecuteReader
- Dim DT As DataTable = New DataTable
- DT.Load(DR)
- '/ Primary Key = ValueMember
- cmbPositionName.ValueMember = "PositionPK"
- '/ Display with field PositionName
- cmbPositionName.DisplayMember = "PositionName"
- '// Bind data source to control.
- cmbPositionName.DataSource = DT
- DR.Close()
- Catch ex As Exception
- MessageBox.Show(ex.Message)
- End Try
- End Sub
คัดลอกไปที่คลิปบอร์ด
เมื่อเราทำการป้อนค่าเข้าไปยัง ComboBox จากนั้นทำการบันทึก (Save) จะต้องไป ตรวจสอบก่อนว่าค่าที่ป้อนเข้าไปใหม่มันมีอยู่แล้วหรือไม่
- ' / --------------------------------------------------------------------------------
- ' / Check duplicate data, If exist data then return <> 0
- Function CheckDuplicateName() As Integer
- ' Blank, and used TRIM for cut the head and tail spaces.
- If Trim(cmbPositionName.Text) = "" Then Return 1
- strSQL = _
- " SELECT Count(tblPosition.PositionName) AS CountName FROM tblPosition " & _
- " WHERE PositionName = " & "'" & Trim(cmbPositionName.Text) & "'"
- If Conn.State = ConnectionState.Closed Then Conn.Open()
- Cmd = New OleDb.OleDbCommand(strSQL, Conn)
- ' Return count records
- CheckDuplicateName = CInt(Cmd.ExecuteScalar)
- End Function
คัดลอกไปที่คลิปบอร์ด หากมีค่าซ้ำมันจะรีเทิร์น หรือส่งค่ากลับมากกว่า 1 ก็ให้ข้ามไป หากมีค่าเป็น 0 แสดงว่าค่าที่ป้อนเข้าไปใหม่ยังไม่มี ก็ให้ทำการบันทึกเข้าสู่ตาราง
แต่ก่อนที่จะบันทึกข้อมูล จะต้องทำการหาค่า Primary Key ตัวใหม่ ซ่ะก่อน
- ' / --------------------------------------------------------------------------------
- ' / Populate Primary Key for new Position Name and Return Primary Key.
- Function SetupNewPK() As Long
- strSQL = " SELECT MAX(tblPosition.PositionPK) AS MaxPK FROM tblPosition "
- If Conn.State = ConnectionState.Closed Then Conn.Open()
- Cmd = New OleDb.OleDbCommand(strSQL, Conn)
- '/ Check exist data and return value
- If IsDBNull(Cmd.ExecuteScalar) Then
- SetupNewPK = 1
- Else
- SetupNewPK = CLng(Cmd.ExecuteScalar) + 1
- End If
- End Function
คัดลอกไปที่คลิปบอร์ด
ทำการบันทึกข้อมูลค่าตำแหน่ง (Position) ใหม่
- ' / --------------------------------------------------------------------------------
- ' / Save data from ComboBox into DataBase
- Private Sub SaveData()
- Try
- ' / Create New Primary Key for PositionName
- Dim PK As Integer = SetupNewPK()
- '/ ------------------------------------------------------------------
- If Conn.State = ConnectionState.Closed Then Conn.Open()
- '// Set your query to a variable(strSQL)
- strSQL = "INSERT INTO tblPosition (PositionPK, PositionName) Values (" & PK & ", '" & Trim(cmbPositionName.Text) & "')"
- Dim DA As OleDb.OleDbDataAdapter = New OleDb.OleDbDataAdapter(strSQL, Conn)
- '// Fill and add or refreshes rows in the dataset
- Dim DS As New DataSet
- DA.Fill(DS)
- '// Refresh data in ComboBox
- Dim strPos As String = Trim(cmbPositionName.Text)
- '// Load Data into ComboBox
- Call PopulateComboBox()
- ' Check value and show
- cmbPositionName.Text = strPos
- cmbPositionName.Focus()
- Catch ex As Exception
- MsgBox(ex.Message)
- End Try
- End Sub
คัดลอกไปที่คลิปบอร์ด Conclusion: นี่คือกระบวนการคิดแบบเป็นขั้นเป็นตอน โดยทำการแยกย่อยงานต่างๆออกมาให้ได้ก่อน จากนั้นทำการเขียนโค้ดและทดสอบว่ามันได้ผลอย่างที่ต้องการหรือไม่ แล้วค่อยตัดต่อไปใช้กับงานจริงต่อไป มันก็จะลดปัญหาเรื่องของข้อผิดพลาดที่เราเรียกกันว่า "Bug" ได้ครับทั่นผู้ชม ... สวัสดี
ดาวน์โหลดโค้ดต้นฉบับ VB.NET (2010) ได้ที่นี่
|
ขออภัย! โพสต์นี้มีไฟล์แนบหรือรูปภาพที่ไม่ได้รับอนุญาตให้คุณเข้าถึง
คุณจำเป็นต้อง ลงชื่อเข้าใช้ เพื่อดาวน์โหลดหรือดูไฟล์แนบนี้ คุณยังไม่มีบัญชีใช่ไหม? ลงทะเบียน
x
|