在 VB.NET 下制作工资管理系统(SQL Server 版) 
内容提要:本文介绍了如何在 VB.NET 下用 ADO.NET 和 SQL Server 2000 制作工资管理系统,
充分运用了 VB.NET 的数据绑定的功能,大大减少代码的编写,通过游标移动机制实现用文本框和
网格控件同步显示数据库中的数据。 
关键字:VB.NET、工资管理系统、SQL Server 
引言:工资管理广泛应用于各行各业,它是公司、企业信息化工程中必不可少的一个环节,所
以学习制作通用的工资管理系统很有必要。本文根据实际需求,制作了一个简单、易用而且适用面
比较广的工资管理系统,其界面友好、功能丰富而不繁杂,并且程序的设计都基于面向对象的思想,
且条理清晰,方便了各企事业单位或机关部门根据自己的实际修改、增强系统功能。 
正文: 
1    简介 
工资管理广泛应用于各行各业,它是公司、企业信息化工程中必不可少的一个环节,所以学习
制作通用的工资管理系统很有必要。本文根据实际需求,制作了一个简单、易用而且适用面比较广
的工资管理系统,其界面友好、功能丰富而不繁杂,并且程序的设计都基于面向对象的思想,且条
理清晰,方便了各企事业单位或机关部门根据自己的实际修改、增强系统功能。 
本系统采用文本框和网格控件同步显示数据的方式,让用户更清晰地从界面了解重要的信息,
也可以让用户快速查看数据,并可以对记录进行添加、删除和修改,还可以根据工号查找历史记录。 
2    设计数据库 
2.1    新建数据库 
打开 SQL  Server  2000 的“企业管理器”,新建一个数据库,取名为“工资管理系统”。如图 1
所示。 
 
图 1 
2.2    建立数据表 
打开“工资管理系统”数据库,右键单击
表的设计如图 2 所示,把“工号”字段设为主键。 
,选择
。 
 
图 2 
※  1    ※ 
选择“总额”字段,把这段设计成计算列。在公式处输入“[基本工资] + [加班费] + [奖金] + [津
贴]”,如图 3 所示。 
被设为计算行上的数据不能通过编程进行修改,所以后面程序设计时,把显示“总额”的项设
图 3 
 
为“只读”。 
保存表,并取名为“工资表”。 
3    建立程序 
本节介绍如何新建程序,如何进行界面设计和数据绑定。 
3.1    新建程序 
打开 VS.NET,新建一个项目,选择
,在右边的“模块”窗口选择“Windows
应用程序”并取名为“工资管理系统”。如图 4 所示。 
图 4 
 
3.2    界面设计 
使用
控件、
控件、
控件和
控件进行窗体的设计,如图 5 所示。 
DataGrid 控件
TextBox 控件
Textbox 控件
Button 控件 
 
图 5 
下面介绍控件的属性设置。如表 1 所示列出了
控件、
控件的属性设置。 
※  2    ※ 
表 1    Label 控件和 TextBox 控件的属性设置 
Text 属性 
控件类型  原(Name)属性  (Name)属性
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
Label 
TextBox 
TextBox 
Label1 
TextBox1 
Label2 
TextBox2 
Label3 
TextBox3 
Label4 
TextBox4 
Label5 
TextBox5 
Label6 
TextBox6 
Label7 
TextBox7 
Label8 
TextBox8 
Label9 
TextBox9 
Label10 
TextBox10 
TextBox11 
 
补充:“TextBox11”控件的
表 2 给出了
工号: 
Label1 
(空) 
TextBox1 
姓名: 
Label2 
(空) 
TextBox2 
性别: 
Label3 
(空) 
TextBox3 
基本工资: 
Label4 
(空) 
TextBox4 
加班费: 
Label5 
(空) 
TextBox5 
奖金: 
Label6 
(空) 
TextBox6 
津贴: 
Label7 
(空) 
TextBox7 
总额: 
Label8 
(空) 
TextBox8 
备注: 
Label9 
(空) 
TextBox9 
请输入员工工号: ——— 
Label10 
(空) 
TxtFind 
(空) 
TxtLocation 
属性选择“Center”,
ReadOnly 属性 
——— 
False 
——— 
False 
——— 
False 
——— 
False 
——— 
False 
——— 
False 
——— 
False 
——— 
True 
——— 
False 
控件的属性设置。 
False 
True 
属性选择“None”。 
表 2    Button 控件的属性设置 
原(Name)属性  (Name)属性  Text 属性 原(Name)属性 (Name)属性  Text 属性
Button1 
Button3 
Button5 
Button7 
Button9 
Button11 
BtTop 
BtNext 
BtFind 
BtAdd 
BtUpdate 
BtExit 
BtPrev 
BtLast 
BtView 
BtDelete 
BtCancel 
 
Button2 
Button4 
Button6 
Button8 
Button10 
 
<< 
>| 
加载数据
删除 
取消 
 
|< 
>> 
查找 
添加 
更新 
退出 
 
“DataGrid1”控件:打开“DataGrid1”控件的窗性窗口,把
“Left”、“Right”四个方向如图 6 所示。改变
时出现交替色。
属性改为“True”。其他属性可以根据开发者的个人爱好进行设置。 
属性选择为“Top”、“Bottom”、
属性的默认属性,让控件显示数据
3.3    数据绑定 
 
图 6 
(1)从工具箱的“数据”部分选择
导 ”。 单 击
, 选 择 数 据 连 接 , 单 击
输 入 服 务 器 名 称 ( 本 机 名 ) , 在
控件在窗体上拖放,进入“数据适配器配置向
按 钮 打 开 “ 数 据 连 接 属 性 ” 窗 口 , 在
中 选 择
(如果您没有在SQL登录的安全性中设置为“SQL  Sever和Windows(S)”
的
输入“sa”同时选中
复选框,在
则不能选择此项),在
※  3    ※ 
下拉框中选择“工资管理系统”再单击
,如果连接成功则显示如图7所示。 
图 7 
 
( 2 ) 单 击
按 钮 关 闭 对 话 框 , 单 击
进 入
对 话 框 , 选 择
单击
。单击
按钮,打开如图8所示的对话框。 
(3)单击
按钮添加“工资表”,再单击
按钮关闭对话框,然后在“查询生成器”对
话框选择
,单击 关闭对话框。最后单击
(4)右键选择添加的
控件,选择
按钮完成向导。 
添加一个数据集,如图9所示。 
                图 8                                                                    图 9 
     
 
(5)选择
在右边的文本框输入“ds”。单击 按钮关闭对话框,这样添加了一个名为
“Ds1”的数据集。 
(6)打开“DataGrid1”控件的属性窗口,在
属性中选择“Ds1”,在
属性中选
择“工资表”。如图10所示。 
(7)打开“TextBox1”控件的属性窗口,打开
属性的树型节点,在 属性中选择
“Ds1”数据集的“工资表”的“工号”字段,如图11所示。 
                图 10                                                                    图 11 
     
 
与上述方法一样,按次序把“TextBox2”到“TextBox9”控件绑定在“工资表”上,绑定的字
段名与对应的
控件的 属性相同。 
※  4    ※ 
3.4    代码编写 
前面已经介绍了如何为控件绑定数据,下面为程序添加代码: 
(1)首先建立一个 TxtLocationChange 过程,用作显示当前活动行所在总行数据的位置,代码
如下: 
Private Sub TxtLocationChange() 
        '中间指示位置变化的文本内容的变化 
        Me.TxtLocation.Text = (((Me.BindingContext(Ds1, "工资表").Position + 1).ToString + "  的  ") 
_ + Me.BindingContext(Ds1, "工资表").Count.ToString) 
End Sub 
(2)当用户单击“添加”按钮时,想让其他按钮不可用,防止用户误操作。因此建立一个 BtEnabled
过程,以一个布尔变量为参数,代码如下: 
Private Sub BtEnabled(ByVal bool As Boolean) 
        '把一个布尔型的参数作为按钮的属性 
        BtView.Enabled = bool 
        BtDelete.Enabled = bool 
        BtUpdate.Enabled = bool 
        BtPrev.Enabled = bool 
        BtLast.Enabled = bool 
        BtNext.Enabled = bool 
        BtTop.Enabled = bool 
        BtFind.Enabled = bool 
End Sub 
(3)单击“加载数据”按钮后在
控件和
控件显示数据,双击“加载数据”按钮
打开代码编辑窗口,在 BtView_Click 过程中添加代码,具体代码如下: 
 
 
Private Sub BtView_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
'填充数据 
'清空数据集 
BtView.Click 
        Try 
                '设定查询语句 
                SqlDataAdapter1.SelectCommand.CommandText = "select * from  工资表" 
                Ds1.Clear()    
                SqlDataAdapter1.Fill(Ds1)   
                Me.DataGrid1.Select(DataGrid1.CurrentRowIndex) '选择当前活动行 
                Me.TxtLocationChange()    
        Catch ex As Exception 
                MsgBox(ex.Message) 
        End Try 
End Sub 
(4)“添加”按钮,前面已经把控件绑定在数据集上,第一次单击此按钮时用 BindingContext
属性的 AddNew()方法添加一行新行,调用 BtEnabled 过程,用“False”作参数,使其他按钮不可用。
当用户输入数据后再一次单击此按钮,再用 BindingContext 属性的 EndCurrentEdit()方法把数据返回
数据集,然后用 SqlDataAdapter1.Update()方法把数据返回数据源,再调用 BtEnabled 过程,用“True”
作参数,使其他按钮可用。最后调用 TxtLocationChange()过程来显示当前活动的数据行,同时在
控件选择当前活动行。双击“添加”按钮,在“BtAdd_Click”过程中添加代码,具体代码
'指示当前活动行的位置 
如下: 
Private Sub BtAdd_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
BtAdd.Click 
        Try 
                If BtAdd.Text = "添加" Then     
                        Me.BindingContext(Ds1, "工资表").AddNew()     
                        BtAdd.Text = "确定" 
                        Me.BtEnabled(False)   
                Else 
                        If BtAdd.Text <> "确定" Then   
 
 
'判断是否第一次按下按钮 
'增加一行新行 
'将其他按钮设为不可用,防止用户误操作 
'用户第二次按下按钮 
※  5    ※ 
'把数据返回数据集 
'更新数据集,调用添加语句 
                                Exit Sub 
                        End If 
                        Me.BindingContext(Ds1, "工资表").EndCurrentEdit()   
                        SqlDataAdapter1.Update(Ds1.工资表)     
                        MsgBox("添加成功!") 
                        BtAdd.Text = "添加" 
                        Me.BtEnabled(True)    
 
                        Me.TxtLocationChange()    
                        Me.DataGrid1.Select(DataGrid1.CurrentRowIndex)     
                End If 
        Catch ex As Exception 
                MsgBox(ex.Message) 
        End Try 
End Sub 
(5)“删除”按钮,单击此按钮实现把当前活动行删除,再调用 TxtLocationChange()过程来显
控件选择当前活动行。双击“删除”按钮,在 BtDelete_Click
'把按钮设为可用 
'指示当前活动行的位置 
'选择活动行 
 
 
 
 
示当前活动的数据行,同时在
过程中添加以下代码,具体代码如下: 
BtDelete.Click 
Private Sub BtDelete_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
        Try 
                '确定是否要删除数据 
                If MsgBox("真的要删除此记录?", MsgBoxStyle.YesNo) = MsgBoxResult.Yes Then 
                        '删除数据集中当前的活动行 
                        Ds1.工资表.Rows(Me.BindingContext(Ds1, "工资表").Position).Delete() 
                        SqlDataAdapter1.Update(Ds1)   
                        Me.TxtLocationChange()    
 
                        Me.DataGrid1.Select(DataGrid1.CurrentRowIndex)     
                End If 
        Catch ex As Exception 
                MsgBox(ex.Message) 
        End Try 
End Sub 
(6)“更新”按钮,单击此按钮把所有数据返回数据集,如果检查到有数据修改过就更新数据,
 
'指示当前活动行的位置 
'更新数据集,调用删除语句 
'选择当前活动行 
否则退出,双击“更新”按钮,在 BtUpdate_Click 过程中添加代码,具体代码如下: 
Private  Sub  BtUpdate_Click(ByVal  sender  As  System.Object,  ByVal  e  As  System.EventArgs) 
Handles BtUpdate.Click 
        Try 
'把数据返回数据集 
                Me.BindingContext(Ds1, "工资表").EndCurrentEdit()   
'判断是否有更改 
                If Ds1.HasChanges(DataRowState.Modified) Then   
 
                '更新数据库,使数据集上经过修改的数据生效于数据库。调用更新语句 
                        SqlDataAdapter1.Update(Ds1) 
                        MsgBox("更改成功!") 
                End If 
        Catch 
        End Try 
End Sub 
“取消”按钮,如果用户第一次单击“添加”按钮,但是又改变主意不再添加则可以单击此按
钮,调用 BindingContext 属性的 CancelCurrentEdit()方法取消添加新行,然后将“添加”按钮的
属性改为“添加”,同时调用 BtEnabled 过程,用“True”作参数,把不可用的按钮为可用。双击“添
加”按钮,在 BtCancel_Click 过程添加代码,具体代码如下: 
Private  Sub  BtCancel_Click(ByVal  sender  As  System.Object,  ByVal  e  As  System.EventArgs) 
Handles BtCancel.Click 
        Me.BindingContext(Ds1, "工资表").CancelCurrentEdit() '取消添加新行 
        BtAdd.Text = "添加" 
※  6    ※ 
        Me.BtEnabled(True) '将部分按钮设为可用 
End Sub 
“退出”按钮,单击此按钮程序退出,双击“退出”按钮,在 BtExit_Click 过程添加代码,具
Private Sub BtExit_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
体代码如下: 
BtExit.Click 
        Application.Exit() 
End Sub 
(7)“查找”按钮,单击此按钮,首先判断查找内容是否为空,如果为空则退出过程,再将带
条件的查询语句赋给“SqlDataAdapter1”控件的 SelectCommand 属性,最后再显示数据,双击“查
找”按钮,在 BtFind_Click 过程中添加代码,具体代码如下: 
Private Sub BtFind_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
BtFind.Click 
        Try 
                If Trim(TxtFind.Text) = "" Then '判断查找内容是否为空,如是为空退出 
                        Exit Sub 
                End If '设定查询语句 
                SqlDataAdapter1.SelectCommand.CommandText  =  "select  *  from  工 资 表  where  工 号 
like '" & TxtFind.Text & "%'" 
                Ds1.Clear() 
                SqlDataAdapter1.Fill(Ds1) '填充数据 
                Me.DataGrid1.Select(DataGrid1.CurrentRowIndex) '选择当前活动行 
                Me.TxtLocationChange() '指示当前活动行的位置 
        Catch 
        End Try 
End Sub 
(8)“>>”(BtNext)按钮,单击此按钮的作用是将活动行指向下一行数据,首先判断是否有
数据可操作,如果没有则退出。取得数据的总行数,判断当前的活动行是否是最后一行,如果不是
最后一行,则将活动行指向下一行,然后调用 TxtLocationChange()过程来显示当前活动的数据行,
同时取消原来的“DataGrid1”选择,再选择下一行。双击“BtNext”按钮,在 BtNext_Click 过程中
添加代码,具体代码如下: 
Private Sub BtNext_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
BtNext.Click 
        If Me.BindingContext(Ds1, "工资表").Count = 0 Then '判断是否有对象,没有则退出 
                Exit Sub 
        End If 
 
        Dim i As Integer '获取数据行的总数 
        i = Me.BindingContext(Ds1, "工资表").Count - 1   
        If Me.BindingContext(Ds1, "工资表").Position < i Then '判断是否已经是最后一行 
                Me.BindingContext(Ds1, "工资表").Position += 1   
'指向当前位置的下一行 
                Me.TxtLocationChange() '指示当前活动行的位置 
        End If 
 
        DataGrid1.UnSelect(DataGrid1.CurrentRowIndex - 1)  '取消原来活动行的选择 
        Me.DataGrid1.Select(DataGrid1.CurrentRowIndex)   
End Sub 
(9)“>|”(BtLast)按钮,单击此按钮的作用是将活动行指向最后一行数据,首先判断是否有
数据可操作,如果没有则退出,然后就把活动行指向最后一行,双击“BtLast”按钮,在 BtLast_Click
过程中添加代码,具体代码如下: 
'选择当前活动行,使之加亮显示 
'列的数据总长度 
Private Sub BtLast_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
BtLast.Click 
        If Me.BindingContext(Ds1, "工资表").Count = 0 Then   
'判断是否有对象,没有则退出 
※  7    ※ 
                Exit Sub 
        End If 
 
        Me.DataGrid1.UnSelect(DataGrid1.CurrentRowIndex)   
        '指定活动行为最后一行 
        Me.BindingContext(Ds1, "工资表").Position = Me.BindingContext(Ds1, "工资表").Count - 1 
        Me.TxtLocationChange()     
        Me.DataGrid1.Select(DataGrid1.CurrentRowIndex)   
End Sub 
(10)“<<”(BtPrev)按钮,单击此按钮首先判断是否有数据可操作,如果没有则退出。判断
当前的活动行是否在第一行,如果不是第一行,则将活动行指向上一行,双击“BtPrev”按钮,在
BtPrev_Click 过程中添加代码,具体代码如下: 
'指示当前活动行的位置 
'选择当前活动行 
'取消原来活动行的选择 
 
 
 
 
 
 
 
 
Private Sub BtPrev_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles 
BtPrev.Click 
        If Me.BindingContext(Ds1, "工资表").Count = 0 Then   
                Exit Sub 
        End If 
 
        If Me.BindingContext(Ds1, "工资表").Position > 0 Then   
                '指向上一行 
                Me.BindingContext(Ds1,  " 工 资 表 ").Position  =  (Me.BindingContext(Ds1,  " 工 资 表
'判断是否有对象,没有则退出 
'判断是否在第一行 
").Position - 1) 
 
 
 
                Me.TxtLocationChange()    
        End If 
 
        DataGrid1.UnSelect(DataGrid1.CurrentRowIndex + 1)   
        Me.DataGrid1.Select(DataGrid1.CurrentRowIndex)   
 
End Sub 
(11)“|<”(BtTop)按钮,单击此按钮,首先判断是否有数据可操作,如果没有则退出,然后
'取消原来活动行的选择 
'选择当前活动行 
'指示当前活动行的位置 
 
 
将活动行指向第一行,双击“BtTop”按钮,在 BtTop_Click 过程添加代码,具体代码如下: 
Private  Sub  BtTop_Click(ByVal  sender  As  System.Object,  ByVal  e  As  System.EventArgs)  Handles 
BtTop.Click 
'判断是否有对象,没有则退出 
        If Me.BindingContext(Ds1, "工资表").Count = 0 Then   
                Exit Sub 
        End If 
 
        Me.DataGrid1.UnSelect(DataGrid1.CurrentRowIndex)   
 
        Me.BindingContext(Ds1, "工资表").Position = 0    
 
        Me.TxtLocationChange()     
 
        Me.DataGrid1.Select(DataGrid1.CurrentRowIndex)   
 
End Sub 
“DataGrid1”的 MouseUp 事件,当鼠标单击“DataGrid1”控件的数据行,当前的活动行也指
向了单击的数据行,文本框的内容也同步改变,程序只需做的工作是选择当前的活动行和显示活动
行的位置。 
 
'指定活动行为第一行 
'指示当前活动行的位置 
'选择当前活动行 
'取消原来活动行的选择 
 
 
 
 
在代码编辑窗口的“类名”下拉框选择“DataGrid1”,在“方法名称”下拉框选择“MouseUp”,
在 DataGrid1_MouseUp 过程中添加代码,具体代码如下: 
Private 
Sub 
DataGrid1_MouseUp(ByVal 
sender 
As 
Object, 
ByVal 
e 
As 
System.Windows.Forms.MouseEventArgs) Handles DataGrid1.MouseUp 
          Try 
                DataGrid1.Select(DataGrid1.CurrentRowIndex) '选择当前活动行 
                Me.TxtLocationChange() '指示当前活动行的位置 
        Catch 
 
                If Err.Number = 9 Then 
※  8    ※