2023年11月27日发(作者:)
DataGridView中直接增删改查的方法—追加了复制粘贴功能
在 增删改
或C#中对于直接DataGridView中的记录,用户更易接受,虽然DataGridView本身
提供Update的方法(该仅需有Select语句即可)可将添加或删除或更新的的记录同时更新至底层数据库,但该方
法模拟Excel的操作,如用户未点击保存按钮,用户此前所做的添加修改或更新的操作无法反映到底层数据库,若
此时有别的用户也在访问该表格,系统所显示的还是旧的数据而不是最新的;另外系统所提供的Update方法仅适
用于单表查询结果的操作,而对于关联表查询的操作则无能为力。
下面的提供的方法所有的操作必须要手动完成,select,update,delete,insert的语句全部有编程人员手动加入。
在DataGridView中可通过其本身直接增加记录,修改记录,以及删除记录。为了保证修改及删除的功能正
常运行,数据库在设计表时必须要添加自动编号ID。
添加记录:
一般添加时,用Insert方法可模拟向数据库添加空白记录,以获取数据库的自动编号,随后利用修改功能输
入其他字段的数据。
修改记录:
修改记录时利用DataGridiView的CellEndEdit事件直接修改,每修改完一个单元格即触发该事件,该事
件再调用Update方法更新到数据库中的记录。避免数据库表中添加了新的字段而必须修改Update 的sql语句。
删除记录:
有了ID后,删除记录也变得更简单,只需将所有欲删除的记录选中,最后由数据库的Delete方法删除选择
的记录。
以上方法每一次动作均直接与数据库关联,保证数据库中的数据都是最新的,一般对于局域网中的操作比较
合适。
直接上项目:
将DataGridView控件拉入窗体中,打开其属性,修改AllowUserToAddRows 与 AllowUserToDeleteRows
均为 False,如下图。
.
同时必须将下面的
删除和添加按钮删除,加入自己的删除按钮
和添加按钮。
表中灰色ID列为不能修改,而其余的列修改即保存。
1
具体代码如下:
Imports
Imports ent
Public Class frmDataGridViewPast
#Region "定义变量"
Private conn As New SqlConnection("server=server;database=dbtest;uid=sa;pwd=sa")
Private da As New SqlDataAdapter()
Private tbl As New DataTable
Private sql As String = ""
Private cmd As New SqlCommand
#End Region
#Region "初始加载"
Private Sub InitLoad()
'初始加载程序
Try
Me.Cursor = rsor
'打开连接
()
sql = "select ID,Number,[Name],age,gender,Address,Telphone,Email from nametable"
tion = conn
dText = sql
dType =
Command = cmd
()
tbl = New DataTable
(tbl)
'定义绑定数据源,以便DataGridview和BindingNavigator 享用同一数据源。
Dim bindSrc As New BindingSource
urce = tbl
Me.urce = bindSrc
gSource = bindSrc
'将DataGridView的列宽设定为所有单元格,每列的宽度以该列中最宽单元格宽度为准显示
2
'该方法不会关闭手动调整列宽的功能.
sizeColumns(ls)
'由于ID是由数据库自动生成的数据,所以此处将其改为只读,不能让用户修改该列内容,而其他的列均可
修改。
s(0).ReadOnly = True
s(0).lor = ray
Catch ex As Exception
'遇到问题就报系统错误!
MsgBox(e)
Finally
Me.Cursor = t
()
End Try
End Sub
Private Sub frmDataGridViewPast_Load(ByVal sender As , ByVal e As rgs) Handles
MyBase.Load
InitLoad()
End Sub
#End Region
#Region "添加新数据"
'注意:此处模拟添加数据给表,只是为了得到一个数据库自动的ID番号,输入后即可按更新的方法直接输入数据
Private Sub tsBtnAddNew_Click(ByVal sender As , ByVal e As rgs) Handles
Try
Me.Cursor = rsor
()
sql = "Insert into nametable(Number)values('')" '仅输入空值,只为能获得数据库的自动ID番号
cmd = New SqlCommand
tion = conn
dType =
dText = sql
eNonQuery() '此处直接将数据保存到底层数据库中
Catch ex As Exception
MsgBox(e)
Finally
3
Me.Cursor = t
()
End Try
'添加完成后再将数据重新加载
InitLoad()
'并且每次输入后,总是将最新输入的记录显示在表的最后部分.
isplayedScrollingRowIndex = nt - 1
End Sub
#End Region
#Region "删除表中选择的数据"
Private Function getDeleteID() As Integer()
'为了方便以后移植到底层类所以此处特将选中的ID先保存至本地数组中
Dim ID() As Integer
ReDim ID()
For i As Integer = 0 To - 1
ID(i) = CInt(edRows(i).Cells(0).Value)
Next
Return ID
End Function
Private Sub DeleteData()
'该方法可同时删除连续选择的多行记录。
'删除数据以表中的ID番号为准,删除时先删除底层的数据然后删除表中的数据
'注意;删除时必须选择整行的数据
Try
Me.Cursor = rsor
()
'删除时从ID的数组中取出该ID,再按该ID番号删除底层数据库中的记录
Dim ID() As Integer = getDeleteID()
For i As Integer = 0 To - 1
sql = "delete from nameTable where ID='" & ID(i) & "'"
cmd = New SqlCommand
tion = conn
dType =
dText = sql
eNonQuery()
Next
4
'删除数据库记录后再删除界面中的记录
Dim x As Integer =
While x > 0
At(edRows(x - 1).Index)
x -= 1
End While
Catch ex As Exception
MsgBox(e)
Finally
Me.Cursor = t
()
End Try
End Sub
Private Sub tsBtnDelete_Click(ByVal sender As , ByVal e As rgs) Handles
DeleteData()
End Sub
#End Region
#Region "修改表中数据直接保存到数据库相应表中"
Private Sub dg1_CellEndEdit(ByVal sender As , ByVal e As
idViewCellEventArgs) Handles dEdit
'当表中的记录有修改时可直接将当前的数据保存至底层数据库中
Try
Me.Cursor = rsor
()
Dim ID As Integer = CInt((0).ng) '一般表的首列为ID,每次有改动
时均以ID作为条件
Dim UpdateFieldName As String = s(Index).ng '修改时以当前单元格
的列名为字段名,
Dim UpdateValue As String = ng '修改后的当前值作为保存到数据库的
值,因使用了字段名称直接等于值的方式,今后数据库表中即使添加了字段也不必在此处添加新的字段,程序自动会根据
DataGridView的字段名及输入后的值直接保存至数据库。
sql = "Update nametable set " & UpdateFieldName & "='" & UpdateValue & "' where ID=" & ID & ""
cmd = New SqlCommand
tion = conn
dType =
5
dText = sql
eNonQuery() '此处直接将数据保存到底层数据库中
Catch ex As Exception
MsgBox(e)
Finally
Me.Cursor = t
()
End Try
End Sub
#End Region
#Region "刷新数据"
Private Sub tsBtnRefresh_Click(ByVal sender As , ByVal e As rgs) Handles
InitLoad()
End Sub
#End Region
’------------------------------------―――――――――――-------
‘新添加了复制粘贴功能
#Region "表格复制粘贴功能"
'关于DataGridView的复制和粘贴一直很困扰,因为要每次粘贴好后,还要能直接保存到数据库表中,所以采取了
'以行为单位作为复制源,粘贴时可选取多行一起粘贴,当然所有的数据均会保存至数据库,保存时以表的ID
'番号为准。
'首先加入快捷菜单,命名为ctMnuForDg1,并添加两子菜单,复制(&C) 和 粘贴(&P),
6
'复制按钮
Private Sub tsMnuCopy_Click(ByVal sender As , ByVal e As rgs) Handles
'注意,选择数据源时,只能选择一行,但同时可选择多个单元格。
'此方法旨在将DataGridView中选择的任意多连续单元格的值复制到剪贴板中
'以便粘贴至其他地方如Excel中或其他的程序中。
Dim CellValue As String = "" '定义粘贴的值
Dim RCount As Integer '当前行数
Dim CCount As Integer '当前列数
Dim MaxRCount As Integer = edCells(0).RowIndex '当前最大行数
Dim MaxCCount As Integer = edCells(0).ColumnIndex '当前最大列数
Dim MinRCount As Integer = edCells(0).RowIndex '最小行数
Dim MinCCount As Integer = edCells(0).ColumnIndex '最小列数
For i As Integer = 1 To - 1
'表中循环获得最大行数,列数和最小行数和列数
RCount = edCells(i).RowIndex
If MaxRCount < RCount Then
MaxRCount = RCount
End If
If MinRCount > RCount Then
MinRCount = RCount
End If
CCount = edCells(i).ColumnIndex
If MaxCCount < CCount Then
MaxCCount = CCount
End If
If MinCCount > CCount Then
MinCCount = CCount
End If
Next
'将每一单元格的值添加到变量中
For i As Integer = MinRCount To MaxRCount
For j As Integer = MinCCount To MaxCCount
If j < MaxCCount Then
CellValue += (i).Cells(j).ng & Chr(9)
Else
CellValue += (i).Cells(j).ng
End If
Next
7
'在剪贴板中最后都要加一空白行,所以此处无需处理。
CellValue += Chr(13) + Chr(10) '注意13在前10在后才有回车效果。
Next
'最后将获得的值输入到剪贴板中
a(, CellValue)
End Sub
'粘贴按钮
Private Sub tsMnuPaster_Click(ByVal sender As , ByVal e As rgs) Handles
Try
Me.Cursor = rsor
() '打开连接
Dim RowChangeChar As String = Chr(13) + Chr(10) '换行字符
Dim ClmChangeChar As String = Chr(9) '列间隔字符
Dim R, C As Integer '选择的行和列的索引
Dim CellValue As String '当前取到的值
CellValue = t().Trim '从剪贴板获得值
Dim RowsCount As Integer = (RowChangeChar).Length
Dim ClmsCount As Integer = (RowChangeChar)(0).Split(ClmChangeChar).Length
Dim SelCount As Integer =
'把行和列的惟一索引分别存储在数组中,然后各自排列,最后再组合在一起。
Dim CIndex_Arr As New ArrayList
Dim RIndex_Arr As New ArrayList
Dim FirstColumnIndex As Integer
Dim FirstRowIndex As Integer
Dim WhereCondition As String '作为更新条件的语句如 where ID='1'
'Dim Prev_R As Integer = edCells(0).RowIndex()
'先将行列索引分别输入各自的数组中
For i As Integer = 0 To SelCount - 1
'
'取得此选择纪录的对于dg的行索引位置
R = edCells(i).RowIndex
8
'取得此选择纪录的对于dg的列索引位置
C = edCells(i).ColumnIndex
RIndex_(R)
CIndex_(C)
Next
'对索引排序
RIndex_()
CIndex_()
FirstColumnIndex = CIndex_Arr(0)
FirstRowIndex = RIndex_Arr(0)
Dim PastStr As String
Dim Row_S As Integer '当前源数据中的行索引
Dim UpdateFieldValue As String '写入到数据库的数据如:字段名='b'
Dim R_Prev As Integer = RIndex_Arr(0)
For i As Integer = 0 To RIndex_ - 1
'依次获得行的索引
R = FirstRowIndex + i
WhereCondition = (R).Cells(0).ng
'依次获得列的索引
'如果i=0为首次计算,然后判断是否不等时才输入,
UpdateFieldValue = ""
For j As Integer = 0 To ClmsCount - 1
PastStr = (RowChangeChar)(Row_S).Split(ClmChangeChar)(j).ToString
C = FirstColumnIndex + j
(R).Cells(C).Value = PastStr
'2014/03/13 修正,更新语句改为末尾处理掉多余的逗号的方式。
UpdateFieldValue += s(C).Name & "='" & PastStr & "',"
Next
'处理掉多余的逗号。
UpdateFieldValue = ing(0, - 1)
9
'该部分语句可迁徙到其他类中,由于是demo所以放在此处。
sql = "Update nametable set " & UpdateFieldValue & " where ID='" & WhereCondition & "'"
cmd = New SqlCommand
tion = conn
dType =
dText = sql
eNonQuery() '此处直接将数据保存到底层数据库中。
'当前行位置,每次累加到末尾,再从头开始。
'即被粘贴的行数超过剪贴板的行数时,再寻坏从0开始,直到选中粘贴的末行为止。
If Row_S = RowsCount - 1 Then
Row_S = 0
Else
Row_S += 1
End If
Next
Catch ex As Exception
MsgBox(e)
Finally
Me.Cursor = t
()
End Try
End Sub
#End Region
以上
10
发布评论