以研究所的设备管理系统为背景,以研究所设备管理模式为研究对象,开发了设备管理系统。设备管理系统是设备管理与计算机技术相结合的产物,根据系统的功能需求分析与定义的数据模式,分析了应用程序的主要功能和系统实现的主要技术。系统主要包括后台数据库的开发和前端应用程序的开发两个方面。考虑了当前设备管理的相关问题,探讨了系统实现的主要相关技术:如数据库技术、C#等。该系统考虑了实际开发的设备管理系统的开发环境、系统流程,主要完成设备类型管理、设备查询、设备档案管理、用户类型管理、用户档案管理,设备征订,设备借用,设备罚款,设备归还以及相应的数据修改,添加,修改等功能。
关键词:管理系统;设备流通;设备管理;用户管理
2.1 系统功能需求
设备管理系统的功能只在具体实现上与研究所的设备管理模式密切相关,总体目标主要是管理设备的各种基本属性数据和设备生命周期中的各种技术档案,改变目前设备资料的管理方式,系统完成日常的查询,统计等各种工作,实现资料电子化管理,把技术人员从大量复杂的统计,汇总等各种工作中解脱出来,实时、准确地为管理人员提供各种数据支持,为决策提供依据,减少决策的盲目性,减少失误。具体地,本文主要体现在以下几个方面:
1.设备的管理:包括设备的类型、设备的借用时间、设备是否在库、设备的修改、删除及查询的处理等;
2.用户的管理:包括用户的姓名,证件,借用日期和归还日期,用户借用设备的权限(这一部分有些功能是预留的待开发功能模块)等操作;
3.设备的流通管理:包括设备征订,设备借用,设备归还,逾期清单,设备罚款等操作。
3.1 系统结构设计
根据对系统要求完成的功能,将系统的功能模块设计为如图1所示。
图1 系统总体功能模块结构图
5.1 主界面
此界面的主要功能是提供所有其他界面的激活功能,界面如图3所示:
在这个界面,可以通过连接进入到其他各个功能模块,具体实现如下:
//----------------------查询MDI子窗体是否存在--------------------------
private bool checkChildFrmExist(string childFrmName)
{ foreach(Form childFrm in this.MdiChildren){
if(childFrm.Name == childFrmName) {//用Name判断,如果存在则将他激活
if(childFrm.WindowState == FormWindowState.Minimized)
childFrm.WindowState = FormWindowState.Normal;
childFrm.Activate();
图3 信息安全研究所设备管理系统主界面
return true;} }
return false; }
private void menuItem2_Click(object sender, System.EventArgs e)
{//通过窗体名称查询该窗体是否已经存在,如存在则显示,否则就新创建一个
if (this.checkChildFrmExist("ReaderClassify")==true)
{ return; }
ReaderClassify newFrm = new ReaderClassify();
newFrm.MdiParent = this;
newFrm.Show(); }
在调用其他界面之前,首先要连接数据库。原程序如下:
tringstrConn=@"DataSource=.\SQLEXPRESS;AttachDbFilename=|DataDirectory|libbook.mdf; Integrated Security=True;Connect Timeout=30;User Instance=True";
SqlConnection cn = new SqlConnection(strConn);
cn.Open();
SqlCommand cmd = cn.CreateCommand();
对于数据库来说,Connection对象是唯一与外界沟通的管道,负责应用程序与数据库服务器实际的链接操作,所以所有对数据库做处理的操作,例如Command数据库之间的沟通都必须依赖与Connection对象。
Cn的含义是定义了一个变量,用来存放数据库连接所创建的对象。
Cn.open()则真正实现了数据库的连接。
在对数据库操作完后,一定要用Close方法关闭Connection对象与数据库的链接,使用该方法时会切断Connection对象与数据库之间的传送通道,并且所有依赖该Connection对象的Command对象都会立即被切断关联;在使用Close方法切断Connection对象与数据库之间的链接之后,可以调用Open方法再次打开该对象;如果Connection对象与数据库正在进行事物处理,那么调用Close方法会造成执行上的错误且所有未完全更新的数据将会丢失,同时Command对象也会自动关闭且丢失相关未更新数据。
5.2 用户管理
- 用户类别设置:
用户类别设置包括了用户的不同类型,用户类型查询,显示全部用户类型,添加新的用户类型,删除用户类型,用户借设备的各种限制。添加用户类型时,为了减少数据的复杂,如果所添类型在数据库中已有,则不在数据库中重复记录。当然在数据库中如果没有该用户类型就记录该类型到数据库中。添加类型信息包括:用户类型,可借设备数,可借特殊设备数,续借次数,借用范围,如图4所示。具体实现如下:
图4 用户类别设置界面
if(
e.Button.ToolTipText == "新增")
{
cmOrders.AddNew();
txt2.Text = "用户类别";
txt3.Text = "1";
txt4.Text = "1";
txt5.Text = "1";
SetModifyMode(true);}
if(e.Button.ToolTipText == "修改")
{SetModifyMode(true);}
if(e.Button.ToolTipText == "删除") {
DialogResult result=MessageBox.Show("确认删除?","删除数据", MessageBoxButtons.OKCancel);
if(result==DialogResult.OK)
if(cmOrders.Count > 0) { //立即从数据集中删除
cmOrders.RemoveAt(cmOrders.Position);
da1.Update(dataSet11); }
- 用户档案管理:
用户档案管理包括了用户编号,姓名查询,显示全部用户,添加用户信息,删除用户信息。添加一个新的用户信息时,为了减少数据的复杂,如果所添用户信息数据库中已有则不再数据库中重复记录。当然在数据库中如果没有该用户信息则记录该信息到数据库中。添加用户信息包括:编号,姓名,性别,类型,出生日期,有效证件,证件号码,联系方式,登记日期,有限期至,操作员,备注,设备借用次数,特殊设备借用次数,是否挂失,如图5所示:
具体实现如下:
int maxID=1;//计算新编号
object result=cmd.ExecuteScalar();
if(
result!=System.DBNull.Value) {
maxID=Convert.ToInt32(result)+1;}
int length=maxID.ToString().Length;
switch(length) {
case 1:txt5.Text="000"+maxID.ToString();break;
case 2: txt5.Text="00"+maxID.ToString();break;
case 3: txt5.Text="0"+maxID.ToString();break;
图5 用户档案管理界面
case 4: txt5.Text=maxID.ToString();break;}
cmb2.SelectedIndex=0;//选择默认类型 }
5.3 设备管理
- 设备类别设置:
设备类别设置分类按照所属类型进行分类:交换设备,服务器,安全性设备,传输,其他设备。可以进行设备设置,更改设备类型名称,可以借用的天数,类型编号,如图6所示:
图6 设备类别设置界面
具体实现如下:
int maxID = 1;//计算新编号
object result = cmd.ExecuteScalar();//返回查询中返回的第一行第一列
if (result != System.DBNull.Value) {
maxID = Convert.ToInt32(result) + 1; }
int length = maxID.ToString().Length;//数值转字符
switch (length) {
case 1:txt3.Text = "00" + maxID.ToString();break;
case 2: txt3.Text = "0" + maxID.ToString();break;
case 3:txt3.Text = maxID.ToString();break; }
txt4.Text = "1";//设置默认可借天数 }
- 设备档案管理:
设备档案管理包括了设备类型,查询设备,显示全部设备,添加设备类型,删除设备分类以及设备信息。添加设备时,为了减少数据的复杂,如果所添加设备在数据库中已有则不再在数据库中重复记录。当然在数据库中如果没有该设备就记录该设备到数据库中。添加设备信息包括:设备编号,设备名,类型,是否在库,公司,批号,加工厂,价格,重量,仓库名称,现存量,库存总量,入库时间,操作员,简介,借出次数,是否注销,如图7所示:
图7 设备档案管理界面
具体实现如下:
cmOrders = (CurrencyManager)BindingContext[dataSet11, "设备信息"];
//设置【加工厂】,【仓库名称】,【类型】三个下拉列表框设置下拉列表
setCombo("select distinct 类型名称from 设备类型", cmb1);
setCombo("select distinct 加工厂名称from 加工厂", cmb2);
setCombo("select distinct 仓库名称from 仓库", cmb3); }
int maxID=1;//计算新编号
object result=cmd.ExecuteScalar();
if(result!=System.DBNull.Value) {
maxID=Convert.ToInt32(result)+1;}
int length=maxID.ToString().Length;
switch(length)//生成新的编码{
case 1:txt5.Text="000000"+maxID.ToString();break;
case 2:txt5.Text="00000"+maxID.ToString();break;
case 3:txt5.Text="0000"+maxID.ToString();break;
case 4:txt5.Text="000"+maxID.ToString();break;
case 5:txt5.Text="00"+maxID.ToString();break;
case 6:txt5.Text="0"+maxID.ToString();break;} }
5.4 流通管理
1.设备征订:
设备征订可以对已有的设备进行征订,通过设备编号来进行征订,征订编号从以被征订的编号开始算起,依次往后加一位,实现顺序排列,如图8所示。具体实现如下:
//-----------显示设备编号时同时显示设备名称--------------
private void txt4_TextChanged(object sender, System.EventArgs e) {
if (txt4.ReadOnly == false || txt4.Text.Trim() == ""){
return; }
//------------调出设备选择窗体,选择设备-------------
private void cmb1_DropDown(object sender, System.EventArgs e) {
cmb1.Text = "";//清空原有设备名
Selectequip newfrm = new Selectequip();//调出新窗口选择设备
newfrm.Text = "双击表格选择设备";
newfrm.ShowDialog();
txt4.Text = equipID;//读入选择的设备信息
图8 设备征订界面
cmb1.Text = equipName; }
//-----------调用储存过程,提交设备征订----------
private void btnSusbribe_Click(object sender, System.EventArgs e) {
SqlCommand cmd = cn.CreateCommand();
cmd.CommandText = "exec sf_设备征订";
try
{cmd.ExecuteNonQuery();
dataSet11.设备征订.Clear();//刷新数据集
da1.SelectCommand.Parameters[0].Value = "%";
da1.SelectCommand.Parameters[1].Value = "%";
da1.Fill(dataSet11); return; }
在这个征订界面中还有嵌入了另外一个查询选择界面,从这个选择界面里面可以选择要进行征订的设备,如图9所示:
具体实现如下:
//-------------双击选择设备-----------------
private void dataGrid1_DoubleClick(object sender, System.EventArgs e) {
int curRow = dataGrid1.CurrentCell.RowNumber;
equipSubscribe.equipID = dataGrid1[curRow, 0].ToString();
equipSubscribe.equipName = dataGrid1[curRow, 1].ToString();
this.Close();}
图9 设备选择界面
2.设备借用:
设备借用模块用户可以借用需要的设备,管理员输入用户号的条形码或编号,然后系统自动调出用户的信息,操作员再输入设备的编号或条形码就可以得到需要借用的设备。点击确定就可以借用该设备。如果点取消借设备则借设备不成功。如果再输入了设备编号而未确定是否借设备就点击退出,系统会提示有设备正在借用,退出无法保存。相同的设备只能借用一次,如果再次输入同样的设备编号系统会提示此设备以借用。如果输入的编号无对应的设备,系统也会提示,如图10所示。具体实现如下:
图10 设备借用界面
if (rbt1.Checked)//判断根据编号查询用户信息还是根据条形码
{cmd.CommandText = "select a.姓名,a.类型,b.设备数量,a.编号from 用户信息a,用户类型b" + " where (a.类型=b.类型)and(a.编号='" + txt1.Text.Trim() + "')"; } else {
cmd.CommandText = "select a.姓名,a.类型,b.设备数量,a.编号from 用户信息a,用户类型b" + " where (a.类型=b.类型)and(a.条形码='" + txt1.Text.Trim() + "')"; }
SqlDataReader dr = cmd.ExecuteReader();//执行查询,并读入用户数据
dr.Read(); return; }
//--------------按回车借设备---------------
private void txt5_KeyPress(object sender, System.Windows.Forms.KeyPressEventArgs e) {
if (e.KeyChar == 13 && txt5.Text.Trim() != "")//获取与按下键相同的字符
{this.borrowequip();//用户借设备 } }
//------------用户借设备-------------
private void borrowequip(){
if (this.totalCount >= Convert.ToInt32(txt4.Text.Trim()))//如果借设备达到上限,则不允许再借
{ MessageBox.Show("已经达到最大借设备数量,请先归还设备后再借设备", "借设备数量达到上限", MessageBoxButtons.OK, MessageBoxIcon.Information);
groupBox2.Enabled = false; return; }{
cmd.CommandText = "select 编号,设备名,加工厂,价格,类型from 设备信息where 编号='" + txt5.Text.Trim() + "'"; }
//计算归还时间
int days = Convert.ToInt32(cmd.ExecuteScalar());
DateTime returnTime = System.DateTime.Now.AddDays(days);//获取当前时间
aRow["应还时间"] = returnTime.ToString();
tblequips.Rows.Add(aRow);//增加新借设备记录
totalCount++; }
3.逾期清单:
模块的主要功能是看到哪些用户的设备逾期了,如图11所示:
具体实现如下:
private void Overdueequip_Load(object sender, System.EventArgs e)
{ da1.SelectCommand.Parameters[0].Value = "%%";
da1.SelectCommand.Parameters[1].Value = "%%";
da1.SelectCommand.Parameters[2].Value = "%%";
da1.Fill(dataSet21);}
图11 逾期清单界面
4.设备归还:
int overDays = 365 * (System.DateTime.Now.Year - rTime.Year) + System.DateTime.Now.DayOfYear - rTime.DayOfYear; //计算过期天数
//根据过期天数计算罚金,台实例中定为每天.2元
decimal fee = (decimal)0.2 * overDays; return (fee); }
图12 设备归还界面
5.设备罚款:
设备罚款模块提供了一个罚款平台,但用户的设备借用逾期时,就会进行相应的罚款,如图13所示。
具体实现如下:
//-----------收取罚款-----------
private void btnPenalty_Click(object sender, System.EventArgs e) {
if (txt4.Text.Trim() == "")
{MessageBox.Show("请输入实收罚款金额", "输入金额", MessageBoxButtons.OK, MessageBoxIcon.Error);
return; }
图13 设备罚款界面
decimal money = Convert.ToDecimal(txt4.Text.Trim());//应收罚款金额
stringpenaltyID=dataGrid1[dataGrid1.CurrentCell.RowNumber,0].ToString().Trim();//罚款记录编号