การสร้างฟอร์มด้วย DataGridView เบื้องต้นแบบ Step by Step [ VB.NET (Windows App+SQL Server) ]
ขั้นตอนเริ่มต้น
เราต้องสร้าง DataSet ใหม่ขึ้นมาก่อน
คลิกขวาที่ชื่อ Project (WindowApplication1) แล้วก็เลือก "Add > New Item..."
ใส่ชื่อ DataSet ในที่นี้ชื่อ MyDataSet แล้วกดปุ่ม "Add"
จะได้หน้าจอ MyDataSet ว่างเปล่า เพื่อสร้าง TableAdapter ต่อไป
Date :
2010-12-17 10:52:34
By :
หางอึ่ง
ขั้นตอนต่อมาคือการสร้าง TableAdapter
ต้องสร้าง 2 ตัวคือ ExpTypeTableAdapter และ MExpenseTableAdapter
เริ่มต้นที่ตัวแรกคือ ExpTypeTableAdapter
คลิกขวา เลือก "Add > Table Adapter..."
จะเห็นหน้าจอให้เลือก Data Connection
กรณีที่ได้สร้างไว้แล้วให้เลือก แล้วกดปุ่ม Next ได้เลย
แต่ถ้ายังไม่เลือกให้กดปุ่ม "New Connection..."
Date :
2010-12-17 10:56:44
By :
หางอึ่ง
หน้าจอการสร้าง DataConnection อาจจะแตกต่างกันไป
เนื่องจากผมใช้ VS2010 Express
หน้าตาจึงได้ประมาณนี้
ให้ลองกดปุ่ม Test Connection เพื่อตรวจสอบว่าใช้งานได้
จากนั้นก็กดปุ่ม OK เพื่อกลับไปหน้าจอสร้าง TableAdapter กันต่อ
Date :
2010-12-17 11:00:20
By :
หางอึ่ง
เลือก DataConnection แล้วกดปุ่ม Next
Date :
2010-12-17 11:02:12
By :
หางอึ่ง
เลือก Use SQL Statement
คลิก Advanced Options
ในที่นี้ผมขอปิด Use optimistic concurrency
Date :
2010-12-17 11:06:35
By :
หางอึ่ง
พิมพ์คำสั่งเลือกข้อมูลตาราง ExpType
หน้านี้ก็ตามค่า Default
แสดงผลว่าสร้างเสร็จแล้ว
จะได้ ExpTypeAdapter และ ExpType DataTable
Date :
2010-12-17 11:10:18
By :
หางอึ่ง
สร้าง MExpenseTableAdapter
ซึ่งมีขั้นตอนเหมือนกับ ExpTypeTableAdapter ทุกอย่าง
ยกเว้นหน้านี้
เมื่อสร้างเสร็จจะได้ประมาณนี้
Date :
2010-12-17 11:13:16
By :
หางอึ่ง
ที่ Data Sources View ควรจะเป็นตามภาพนี้
หลังจากสร้าง TableAdapter เสร็จแล้ว
ก็เป็นการสร้างฟอร์ม
คลิกขวาที่ชื่อ Project แล้วเลือก "Add > Window Form"
ใส่ชื่อฟอร์ม
Date :
2010-12-17 11:17:38
By :
หางอึ่ง
ลาก MExpense จาก MyDataSet มาใส่ในฟอร์ม
VS จะสร้าง DataGridView มาให้ทันที
พร้อมกับ Component ที่อยู่ข้างล่าง
ขอเปลี่ยนชื่อ Component เป็นดังนี้
Date :
2010-12-17 11:21:21
By :
หางอึ่ง
คลิกที่ DataGridView เลือกเป็น Dock in Parent Container
ตอนนี้ ExpTypeID ใน DataGridView ยังเป็น TextBox อยู่
ขั้นตอนต่อไปเราจะเปลี่ยนเป็น ComboBox
ก่อนอื่นต้อง Add BindingSource
ที่ BindingSource ใหม่นี้
ให้เปลียน DataSource เป็น dsMain
DataMember เป็น ExpType
Date :
2010-12-17 11:28:19
By :
หางอึ่ง
เข้าไปแก้ไข Columns คลิก "Edit Columns."
ต้องการแก้ไข Column ExpTypeID เป็น ComboBox
คลิกที่ ExpTypeID ที่ Property ColumnType ด้านขวา เปลี่ยนเป็น DataGridViewComboBoxColumn
เปลี่ยนคุณสมบัติ ที่เกี่ยวข้องกับการ Binding Data ตามภาพข้างล่าง
DataSource: bsExpTypeID
DisplayName: ExpTypeName
ValueMember: ExpTypeID
สลับลำดับ Column ด้วยลูกศรขึ้น-ลง
แก้ไขคุณสมบัติอื่นตามต้องการ
เช่น ReadOnly
เมื่อแก้ไขทุกอย่างพร้อมแล้ว ก็กดปุ่ม "OK"
Date :
2010-12-17 12:43:17
By :
หางอึ่ง
ลองเข้าไปดู Code View
จะเห็น Code ตามข้างล่างนี้
ซึ่ง VS จัดการสร้างให้อัตโนมัติ
สามารถแก้ไขได้ตามความต้องการ
Code (VB.NET)
Public Class TestDataGrid
Private Sub MExpenseBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MExpenseBindingNavigatorSaveItem.Click
Me.Validate()
Me.bsMExpense.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.dsMain)
End Sub
Private Sub TestDataGrid_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
'TODO: This line of code loads data into the 'MyDataSet.MExpense' table. You can move, or remove it, as needed.
Me.ExpTypeTableAdapter.Fill(Me.dsMain.ExpType)
'TODO: This line of code loads data into the 'MyDataSet.MExpense' table. You can move, or remove it, as needed.
Me.taMExpense.Fill(Me.dsMain.MExpense)
End Sub
End Class
Date :
2010-12-17 12:47:31
By :
หางอึ่ง
ขอบคุณ +1 สำหรับบทความดี ๆ ครับ เก็บลงคลังกระทู้ให้เรียบร้อยแล้วครับ
Date :
2010-12-17 12:52:06
By :
webmaster
ในที่นี้ ผมต้องการ
1. ComboBox ExpTypeID ซึ่งเป็น Combo ที่ดึงข้อมูลจากตาราง ExpType มาแสดง
โดยต้องการให้แสดงรายการข้อมูล เฉพาะที่ ExpTypeID>0 จึงเข้าไปแก้ไขที่ Event Form.Load
2. ให้บันทึกผู้แก้ไข วันที่แก้ไข วันที่เพิ่มรายการ ผู้เพิ่มรายการ
3. ผมขอใช้ TableAdapter ในการ Update ตาราง ไม่ใช้ TableAdapterManager เอาไว้ให้ระดับที่ชำนาญกว่านี้ ค่อยมาคุยเรื่อง TableAdapterManager กันใหม่
Code (VB.NET)
Public Class TestDataGrid
Private Sub MExpenseBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MExpenseBindingNavigatorSaveItem.Click
Me.Validate()
Me.bsMExpense.EndEdit()
'---------------------------------------------
' ใส่ข้อมูลผู้ใช้งาน และวันที่แก้ไขตรงนี้
'---------------------------------------------
Dim stUser As String
Dim SysDate As Date = Date.Now
stUser = My.User.Name
stUser = "CurrentUser" ' ของจริงบรรทัดนี้ไม่ต้องใส่
For Each dr As DataRow In Me.dsMain.MExpense.Rows
If (dr.RowState And 20) > 0 Then ' เช็คกับ 20 ถ้าเป็นจริง แสดงว่าเป็นการเพิ่มหรือไม่ก็แก้ไข
If dr.RowState = DataRowState.Added Then
dr("usrInsert") = stUser
dr("dtInsert") = SysDate
End If
dr("usrModify") = stUser
dr("dtModify") = SysDate
End If
Next
'---------------------------------------------
' แก้ไขตรงนี้
'---------------------------------------------
' Me.TableAdapterManager.UpdateAll(Me.dsMain)
Me.taMExpense.Update(Me.dsMain.MExpense)
End Sub
Private Sub TestDataGrid_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
' เนื่องจากใน Combo ExpTypeID ต้องการแสดงรายการที่ ExpTypeID>0 จึงต้องแก้ไขคำสั่ง
' Me.ExpTypeTableAdapter.Fill(Me.dsMain.ExpType)
Dim SQL As String = "SELECT ExpTypeID, ExpTypeName FROM ExpType WHERE ExpTypeID>0"
Dim da As New SqlClient.SqlDataAdapter(SQL, My.Settings.BudgetConnectionString)
da.Fill(Me.dsMain.ExpType)
'TODO: This line of code loads data into the 'MyDataSet.MExpense' table. You can move, or remove it, as needed.
Me.taMExpense.Fill(Me.dsMain.MExpense)
End Sub
End Class
ประวัติการแก้ไข 2010-12-21 10:21:42
Date :
2010-12-17 12:53:20
By :
หางอึ่ง
ลองรันแล้วใส่ข้อมูล
สังเกต Column ExpID ได้รหัสติดลบ
ซึ่งถูกต้องแล้ว
เมื่อกดปุ่มบันทึก (รูปแผ่นดิสก์)
จะได้รหัส ExpID เป็นบวกนั่นคือ ข้อมูลเหล่านี้ได้ถูกบันทึกสมบูรณ์แล้ว
ประวัติการแก้ไข 2010-12-17 12:58:23
Date :
2010-12-17 12:56:25
By :
หางอึ่ง
ที่ได้รหัสตอนแรกเป็นลบ
เพราะ VS ได้กำหนดให้ ExpID ในตาราง Expense เป็น AutoNumber แบบลบทีละ 1
ด้วยเหตุผลบางประการ
อย่าพยายามไปแก้มันนะครับ
Date :
2010-12-17 13:01:38
By :
หางอึ่ง
Instance ExpTypeTableAdapter ถูกสร้างอัตโนมัติโดย VS
ซึ่งเราไม่ได้ใช้ ลบทิ้งได้
Date :
2010-12-17 13:03:57
By :
หางอึ่ง
ขอบคุณมากค่ะ ได้ความรู้เพิ่มขึ้นจริงๆ
Date :
2011-07-14 10:09:42
By :
แค่เด็กตัวเล๊กๆคนนึง
ขอบคุณมากครับ สำหรับตัวอย่างดี ๆแบบนี้
ผมมีคำถาม รบกวนด้วยครับ
ผมทดลองทำตามตัวอย่าง แต่พบปัญหาคือ เมื่อเรากรอกข้อมูลลงใน datagrid แล้ว
เมื่อกด save ข้อมูลเหมือนจะไม่เข้าใน database คือเมื่อ End Program แล้ว run program ใหม่
ข้อมูลบน datagrid จะว่างหมดเลยครับ
Date :
2011-07-24 12:40:27
By :
Somporn
ใช้ฐานข้อมูลอะไรขอรับ
SQL Compact รึเปล่า
หรือ MS Access
Date :
2011-07-24 19:15:37
By :
watcharop
ลองทั้ง 2 แบบแล้วเป็นเหมือนกันครับ
แต่พอทำ เป็น file setup พอ install ลงเครื่องแล้วลองใช้งานได้ปกติ
เข้าใจว่าน่าจะเป็นเพราะช่วงพัฒนา Program มันเป็นข้อมูลชั่วคราวหรือเปล่า พอออกจากโปรแกรมข้อมูลใน
Database หายหมด แต่ระหว่างเขียนโปรแกรมข้อมูลยังอยู่ครับ
แบบว่ามันแปลกๆๆ
Date :
2011-07-24 20:24:23
By :
Somporn
อาจเป็นเพราะทุกครั้งที่รันใน VS
VS Copy database ไปไว้ในโฟลเดอร์ Debug ทำให้เกิดการทับข้อมูลเก่า
ไม่รู้คุณเขียนโค้ดให้ Connect กับฐานข้อมูลที่อยู่โฟลเดอร์เดียวกับโปรแกรมรึเปล่า
ซึ่งถ้าเป็นเช่นนั้น นั่นแหละคือคำตอบ
Date :
2011-07-24 22:24:59
By :
watcharop
พี่ครับ ผมมือใหม่มากๆ ..พอจะมีแนวทางสอนทำปุ่ม Save ให้มันทำงานได้ไหมฮะ
อีกอย่าง เพราะผมใช้ MySQL รึเปล่า ช่องบางช่องตอน สร้าง new connect มันไม่ให้ติ๊กถูกตามภาพด้วยอ่า เกี่ยวไหมครับ
ประวัติการแก้ไข 2011-12-24 00:23:35
Date :
2011-12-24 00:21:35
By :
shadowromeo
ขอถามคุณหางอึ่งหน่อยครับ
โดยปกติเวลาเราเซฟข้อมูลที่มีการแก้ไขเราจะกดปุ่มเซฟ(รูปแผ่นดิสก์)ที่คอนโทรล BindingNavigator ใช่ไหม่ครับ
ที่นี้ถ้าฟอร์มที่ผมออกแบบไม่ได้ใช้ตัวคอนโทรล BindingNavigator จะเขียนคำสั่งให้มันเซฟข้อมูลลง database อย่างไรครับ
เช่นอาจต้องเขียนคำสั่งอะไรซักอย่างตอนที่เรากำลังจะปิดฟอร์ม อะไรประมาณเนี้ยครับ
ตย. ไม่รู้ว่าผมคิดถูกหรือเปล่านะครับ
private void MyForm_FormClosing(object sender, FormClosingEventArgs e)
{
//คำสั่งให้ update ข้อมูลลงใน database
}
ปล.ผมเดาเอาเองนะครับว่าควรจะต้องเขียนลงใน FormClosing event
อีกอย่างหนึ่งครับ ผมใช้ภาษา c# นะครับ แต่ถ้าคุณหางอึ่งไม่สะดวก จะตอบมาเป็นภาษา vb ก็ได้ครับ
ขอบคุณครับ
ประวัติการแก้ไข 2012-05-01 20:00:15
Date :
2012-05-01 19:58:34
By :
geo1209
เมื่อจะบันทึกก็เรียกคำสั่งข้างล่างนี้
เป็นการบันทึกตาราง MExpense
ซึ่งจะอยู่ Event ไหนก็ได้
Me.taMExpense.Update(Me.dsMain.MExpense)
Date :
2012-05-02 09:53:08
By :
watcharop
มือใหม่ค่ะ รบกวนผู้รู้ช่วยหน่อยค่ะ ทำโปรเจ็คจบ แต่ติดขั้นตอนการคำนวณ ใช้ Database SQL Server 2008 R2 และ เขียนด้วย VB 2010 ค่ะ
หน้าจอนี้พอดึงข้อมูลจากใบสั่งซื้อเข้ามาแล้จะทำการบันทึกมันไม่ได้ค่ะฟ้อง
Code (VB.NET)
Private Sub BtnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles BtnSave.Click
connection = New SqlConnection(conStr)
If connection.State = ConnectionState.Closed Then
connection.Open()
End If
BtnSearch.Enabled = False
BtnSave.Enabled = False
BtnExit.Enabled = True
Dim CusID As String = txtID.Text
Dim processID As String = Process_ID.Text
Dim POID As String = PO_ID.Text
Dim Remarks As String = Remark.Text
Dim MSG As String = ""
If status = "S" Then
MSG = "คุณต้องการเพิ่มข้อมูล ใช่หรือไม่?"
ElseIf status = "E" Then
MSG = "คุณต้องการแก้ไขข้อมูล ใช่หรือไม่?"
End If
If MessageBox.Show(MSG, "คำยืนยัน", MessageBoxButtons.YesNo, MessageBoxIcon.Information) = Windows.Forms.DialogResult.Yes Then
Select Case UCase(status)
Case "S"
Dim sql As String = "INSERT INTO Process_Product(Process_ID,PO_ID,Cus_ID,Date_Process,Date_Receiving_Pro, Remark) values ('" & processID & "','" & POID & "','" & CusID & "','" & DateTimeProcess.Value.AddYears(-543).ToString("MM/dd/yyyy") & "','" & DateTimeReceProcess.Value.AddYears(-543).ToString("MM/dd/yyyy") & "','" & Remarks & "')"
Dim cmd2 As New SqlCommand(sql, connection)
Dim adapter As New SqlDataAdapter(cmd2)
Dim data As New DataSet()
cmd2.Parameters.Clear()
cmd2.ExecuteNonQuery()
Dim data3 As New DataSet()
Dim sql3 As String = "Insert into Process_Product_ Lists(Process_ID, Product_ID, Qty, Unit) values (@Process_ID, @Product_ID, @Qty, @Unit)"
'MessageBox.Show(sql3)
Dim cmd3 As New SqlCommand(sql3, connection)
For i As Integer = 0 To MyDataGridView1.RowCount - 2
With cmd3
.Parameters.AddWithValue("processID", (Process_ID.Text))
.Parameters.AddWithValue("Product_ID", MyDataGridView1.Rows(i).Cells(0).Value)
'.Parameters.AddWithValue("Price", MyDataGridView1.Rows(i).Cells(2).Value)
.Parameters.AddWithValue("Qty", CDbl(MyDataGridView1.Rows(i).Cells(2).Value))
.Parameters.AddWithValue("Unit", MyDataGridView1.Rows(i).Cells(3).Value)
End With
cmd3.ExecuteNonQuery()
cmd3.Parameters.Clear()
Next i
MessageBox.Show("บันทึกข้อมูลเรียบร้อยแล้ว", "ข้อความ", MessageBoxButtons.OK, MessageBoxIcon.None)
' End If
'End If
clear()
MyDataGridView1.Columns.Clear()
MyDataGridView1.Rows.Clear()
MyDataGridView1.DataSource = Nothing
DataGrid1()
BtnSave.Enabled = False
BtnSearch.Enabled = False
BtnDelete.Enabled = False
MyDataGridView1.Enabled = False
Process_ID.Enabled = True
PO_ID.Enabled = False
locktext()
Case "E"
'Dim sql As String = "Update Process_Product set Date_Process ='" & DateTimeProcess.Value.AddYears(-543).ToString("MM/dd/yyyy") & "',"
'sql &= "Cus_ID ='" & txtID.Text & "',"
''sql &= "Amount1 ='" & Amount1.Text & "',"
''sql &= "Discount ='" & Discount.Text & "',"
''sql &= "SumDis ='" & SumDiscount.Text & "',"
''sql &= "Amount2 ='" & Amount2.Text & "',"
''sql &= "Vat ='" & Vat.Text & "',"
''sql &= "SumVat ='" & SumVat.Text & "',"
''sql &= "Total ='" & Total.Text & "',"
''sql &= "Remark ='" & Remark.Text & "'WHERE Accounts_ID ='" & Account_ID.Text & "'"
'Dim cmd As New SqlCommand(sql, connection)
'Dim cmd1 As New SqlCommand(sql, connection)
''For i As Integer = 0 To DataGridView2.RowCount - 2
'With cmd1
' Dim sql2 As String = "Delete From Process_Product_ Lists Where Process_ID='" & Process_ID.Text & "'"
' With cmd1
' .CommandType = CommandType.Text
' .CommandText = sql2
' .Connection = connection
' .ExecuteNonQuery()
' End With
' cmd1.ExecuteNonQuery()
' cmd1.Parameters.Clear()
'End With
''Next i
'Dim sql3 As String = "Insert into Process_Product_ Lists(Process_ID,Product_ID, Qty, Unit) values (@ProcessID,@Product_ID,@Qty, @Unit)"
'Dim cmd3 As New SqlCommand(sql3, connection)
'For i As Integer = 0 To MyDataGridView1.RowCount - 2
' With cmd3
' .Parameters.AddWithValue("Process_ID", (Process_ID.Text))
' .Parameters.AddWithValue("Product_ID", MyDataGridView1.Rows(i).Cells(0).Value)
' '.Parameters.AddWithValue("Price", MyDataGridView1.Rows(i).Cells(2).Value)
' .Parameters.AddWithValue("Qty", CDbl(MyDataGridView1.Rows(i).Cells(2).Value))
' .Parameters.AddWithValue("Unit", CDbl(MyDataGridView1.Rows(i).Cells(3).Value))
' End With
' cmd3.ExecuteNonQuery()
' cmd3.Parameters.Clear()
'Next i
'With cmd
' .CommandType = CommandType.Text
' .CommandText = sql
' .Connection = connection
' .ExecuteNonQuery()
'End With
'cmd.ExecuteNonQuery()
'cmd.Parameters.Clear()
'MessageBox.Show("แก้ไขข้อมูลเรียบร้อยแล้ว", "ข้อความ", MessageBoxButtons.OK, MessageBoxIcon.None)
'clear()
'MyDataGridView1.Columns.Clear()
'MyDataGridView1.Rows.Clear()
'MyDataGridView1.DataSource = Nothing
'DataGrid1()
'BtnSave.Enabled = False
'BtnAdd.Enabled = True
'BtnSearch.Enabled = False
'BtnDelete.Enabled = False
'MyDataGridView1.Enabled = False
'PO_ID.Enabled = True
'Process_ID.Enabled = False
'locktext()
End Select
End If
End Sub
Date :
2012-05-17 10:37:32
By :
surinda
ขอบคุณคับ^^
Date :
2013-09-06 17:13:24
By :
TheSkyPy
Date :
2013-09-18 15:41:33
By :
kkk
ขอถามเพิมเติมหน่อยค่ะ ถ้าเกิดว่า อิมพอร์ตไฟล์ Excel ให้เข้ามาอยู่ในรูป datagridview ได้แล้วถ้าต้องการแก้ไขบางเซลล์ในนั้น Ex.ค่าตัวเลข
ซึ่งเมื่อแก้ไขแล้ว คอมลัมภ์สุดท้ายซึ่งเป็น total ค่ะ ต้องการให้มันเปลี่ยนค่าตามที่แก้ตัวเลขไปอ่ะค่ะ คือตอนนี้มันไม่เปลี่ยนค่าให้
มันค้างค่าตอนที่ยังไม่ได้เปลี่ยนค่าตัวเลขไว้ค่ะ จะแก้ยังไงอ่ะคะ รบกวนด้วยนะคะ
Date :
2013-11-07 12:08:48
By :
alice
อยากได้ตัวอย่างโค้ด vb.net Import ข้อมูลจาำกไฟล์ Excel เข้า Access ค่ะ รบกวนด้วยนะคะ
Date :
2013-11-08 10:00:29
By :
annsan
แล้วถ้าต้องการไม่ให้คอลัมน์ใน DataGrid ไม่สามารถทำงานได้ล่อครับ
คือไม่อยากให้คอลัมน์ รหัสสินค้าทำงานได้ แต่ยังแสดงบน Datagrid อยู่
โค้ด dagrid.enable = false
ได้ไหมครับ
Date :
2017-08-20 12:05:34
By :
zen
Load balance : Server 05