thongkorn โพสต์ 2018-4-27 13:49:58

[VB.NET] การแทรกไอเทมให้กับ ComboBox Control ทั้งแบบ Bound และ UnBound Data

http://www.g2gnet.com/webboard/images/vbnet/ContactPositionReport.png


เวลาที่เราเชื่อมความสัมพันธ์ของตารางข้อมูลในแบบ One-To-One การจะโหลดข้อมูลจากตารางย่อย (Detail Table) เข้ามาสู่ ComboBox Control ก็สามารถทำได้ทั้งแบบ Bound และ UnBound Data ซึ่งโค้ดตัวอย่างนี้จะเป็นการนำไปใช้งานจริง ในกรณีที่เราต้องการให้ผู้ใช้ เลือกรายชื่อของบุคคลในแต่ละแผนก ไปพิมพ์รายงาน แต่ปัญหาจะเกิดขึ้นเมื่อต้องการให้เลือกพิมพ์รายชื่อทั้งหมดออกไป ซึ่งรายการนี้มันไม่ได้อยู่ในตารางย่อย (tblPosition หรือตารางตำแหน่ง) ดังนั้นเราจึงต้องทำการเพิ่มไอเทม (Item) เข้าไปแทรกในตำแหน่งแรกสุด (หรือจะที่ไหนๆก็ได้) เพื่อเป็นทางเลือกให้กับผู้ใช้งาน ... แอดมินไม่ขอลงรายละเอียดในเรื่อง DataTable และ DataRow แต่มันคือหัวใจสำคัญในการแก้ปัญหา ดังนั้นทุกๆท่านควรจะต้องไปศึกษาเพิ่มเติมเอาเองนะครับ ...


http://www.g2gnet.com/webboard/images/vbnet/ContactPosition.png
การ Join ของ 2 ตาราง ซึ่งเราจะโฟกัสไปที่ตารางรายชื่อบุคคล (tblContact) เป็นหลัก มันจึงถูกเรียกว่า Master ...


http://www.g2gnet.com/webboard/images/vbnet/ContactPositionShowall.png
ตารางข้อมูลตำแหน่ง (tblPosition) เพราะมันเป็นส่วนที่ต้องไปเชื่อมกับตารางหลัก (tblContact) มันจึงเป็นระดับตารางย่อย หรือ Detail ... ขอให้สังเกตว่ามันจะไม่มีข้อมูลเพื่อให้แสดงผลข้อมูลทั้งหมด


โค้ดในส่วนของการ Bound Data ให้กับ ComboBox Control ...
    ' / --------------------------------------------------------------------------------
    ' / Load Position data into ComboBox (Bound Data)
    Private Sub BoundComboBox()
      strSQL = "SELECT * FROM tblPosition ORDER BY PositionName "
      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"
            cmbPositionName.DataSource = DT

            '// Insert new row.
            Dim DTRow = DT.NewRow()
            DTRow("PositionPK") = 0
            DTRow("PositionName") = "Show All"
            DT.Rows.InsertAt(DTRow, 0) ' //insert new row to index 0.
            cmbPositionName.SelectedIndex = 0

      Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try
    End Sub

โค้ดในส่วนของการ UnBound Data ให้กับ ComboBox Control ...
    ' / --------------------------------------------------------------------------------
    ' / Load Position data into ComboBox (UnBound Data)
    Private Sub UnBoundComboBox()
      strSQL = "SELECT * FROM tblPosition ORDER BY PositionName "
      Try
            If Conn.State = ConnectionState.Closed Then Conn.Open()
            Cmd = New OleDbCommand(strSQL, Conn)
            DR = Cmd.ExecuteReader()
            Dim DT As New DataTable
            DT.Columns.Add("PositionPK", GetType(Integer))
            DT.Columns.Add("PositionName", GetType(String))
            '// Populate the DataTable to binding for the Combobox.
            Dim DTRow As DataRow
            While DR.Read
                If DR.HasRows Then
                  DTRow = dt.NewRow()
                  DTRow("PositionPK") = DR("PositionPK")
                  DTRow("PositionName") = DR("PositionName")
                  dt.Rows.Add(DTRow)
                End If
            End While
            '// Insert new row. (This sample is the first item.)
            DTRow = dt.NewRow
            DTRow("PositionPK") = 0
            DTRow("PositionName") = "Show All"
            DT.Rows.InsertAt(DTRow, 0) ' //insert new row to index 0.
            '//
            With cmbPositionName
                .DataSource = DT
                .ValueMember = "PositionPK"
                .DisplayMember = "PositionName"
                .SelectedIndex = 0
            End With
            DR.Close()
      Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try
    End Sub

ส่วนโค้ดที่เหลือทั้งหมด ...
' / --------------------------------------------------------------------------------
' / Developer : Mr.Surapon Yodsanga (Thongkorn Tubtimkrob)
' / eMail : thongkorn@hotmail.com
' / URL: http://www.g2gnet.com (Khon Kaen - Thailand)
' / Facebook: http://www.facebook.com/g2gnet (For Thailand only)
' / Facebook: http://www.facebook.com/CommonIndy (Worldwide)
' / Purpose: Adding a row for Bound & UnBound Data into ComboBox.
' / Microsoft Visual Basic .NET (2010) + MS Access 2007+
' /
' / This is open source code under @CopyLeft by Thongkorn Tubtimkrob.
' / You can modify and/or distribute without to inform the developer.
' / --------------------------------------------------------------------------------
Imports System.Data.OleDb

Public Class frmComboBoxManage

    Dim Conn As OleDbConnection
    Dim Cmd As OleDbCommand
    Dim DA As OleDbDataAdapter
    Dim DR As OleDbDataReader
    Dim strSQL As String

    ' / --------------------------------------------------------------------------------
    ' / Connect to the DataBase.
    Public Function ConnectDataBase() As System.Data.OleDb.OleDbConnection
      Dim strPath As String = Application.StartupPath
      strPath = strPath.ToLower()
      strPath = strPath.Replace("\bin\debug", "\")
      If Microsoft.VisualBasic.Right(strPath, 1) <> "\" Then strPath = strPath + "\"
      '//
      Dim strConn As String = _
            "Provider = Microsoft.ACE.OLEDB.12.0;"
      strConn += _
            "Data Source = " & strPath & "Contact.accdb"

      Dim Conn As OleDb.OleDbConnection = New OleDb.OleDbConnection(strConn)
      '// Connection (Conn)
      Conn.ConnectionString = strConn
      '// Return Connection
      Return Conn
    End Function

    ' / --------------------------------------------------------------------------------
    Private Sub frmComboBoxManage_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
      '// Initialize DataGridView
      With dgvData
            .RowHeadersVisible = False
            .AllowUserToAddRows = False
            .AllowUserToDeleteRows = False
            .AllowUserToResizeRows = False
            .MultiSelect = False
            .SelectionMode = DataGridViewSelectionMode.FullRowSelect
            .ReadOnly = True
            '/ Autosize Column
            .AutoSizeColumnsMode = DataGridViewAutoSizeColumnsMode.Fill
            .AutoResizeColumns()
      End With

      '/ Connect to database
      Conn = ConnectDataBase()
      '/ Choose one, Bound or UnBound.
      'Call BoundComboBox()
      Call UnBoundComboBox()
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / Bound Data into GridView
    Private Sub FillGrid(Grid As DataGridView)
      Try
            Dim DT As New DataTable
            Dim sRow As Integer
            '// Remove rows.
            If Grid.Rows.Count > 0 Then
                While sRow < Grid.Rows.Count
                  Grid.Rows.RemoveAt(sRow)
                End While
            End If
            '//
            strSQL = _
                  "SELECT tblContact.ContactPK, tblContact.Fullname, tblPosition.PositionName " & _
                  "FROM tblContact INNER JOIN tblPosition ON tblContact.PositionFK = tblPosition.PositionPK "
            '// Conditions for position selection.
            If cmbPositionName.SelectedIndex <> 0 Then
                strSQL = strSQL & _
                  " WHERE PositionFK = " & cmbPositionName.SelectedValue
            End If
            strSQL = strSQL & " ORDER BY ContactPK"
            If Conn.State = ConnectionState.Closed Then Conn.Open()
            Cmd = New OleDb.OleDbCommand(strSQL, Conn)
            DR = Cmd.ExecuteReader
            DT.Load(DR)
            Grid.DataSource = DT
            DR.Close()

      Catch ex As Exception
            MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error)
      End Try
    End Sub

    ' / --------------------------------------------------------------------------------
    ' /
    Private Sub btnData_Click(sender As System.Object, e As System.EventArgs) Handles btnData.Click
      '// Show Data
      Call FillGrid(dgvData)
    End Sub

    ' / --------------------------------------------------------------------------------
    ' / Show ComboBox Information.
    Private Sub btnInfo_Click(sender As System.Object, e As System.EventArgs) Handles btnInfo.Click
      '// Trap Error
      If Not IsDBNull(cmbPositionName.SelectedValue) Then
            MessageBox.Show( _
                "You can send a Primary Key to SQL for display only this position." & vbCrLf & _
                "Primary Key is " & cmbPositionName.SelectedValue & vbCrLf & _
                "Position name: " & cmbPositionName.Text)
      End If
    End Sub

    Private Sub frmComboBoxManage_FormClosed(sender As Object, e As System.Windows.Forms.FormClosedEventArgs) Handles Me.FormClosed
      If Conn.State = ConnectionState.Open Then Conn.Close()
      Me.Dispose()
      Application.Exit()
    End Sub

End Class

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

kriangsak โพสต์ 2018-4-28 10:27:57

อ.ครับ error : The 'Microsoft.ACE.OLEDB.12.0' provider is not registered on the local machine. จะแก้ไขยังไงครับ

thongkorn โพสต์ 2018-4-28 10:34:46

ไปที่ Project Properties --> Compile --> Advanced Compiler Settings ... เปลี่ยน Target CPU ให้เป็น x86 ครับผม
หน้า: [1]
ดูในรูปแบบกติ: [VB.NET] การแทรกไอเทมให้กับ ComboBox Control ทั้งแบบ Bound และ UnBound Data