VisualBasic.NET快速开发MIS系统

时间:2007-06-15 来源: 作者: 【字体: 减小 增大收藏 | 投稿
  
【摘要】本文介绍微软最新技术VisualBasic.NET在数据库开发方面的应用。结合数据库系统开发的知识,介绍了物理表操作的方法,利用VisualBasic.NET的面向对象的特征,利用类的继承知识,简化了数据库系统开发过程。

  引言

  以前版本的VisualBasic虽然号称自己是一种OOP(面向对象)编程语言,但却不是一个地地道道的OOP编程语言,最多只是半个面向对象的编程语言。但VisualBasic.NET已经是一种完全的面向对象的编程语言。他支持面向对象的所有基本特征:继承、多态和重载。这使得以前在VisualBasic中很难或根本实现不了的问题,在VisualBasic.NET中可以顺利的用简单的方法实现。

  自定义数据操作类

  定义一个数据访问的基类,并编写有关数据库操作的必要方法。

  定义一个数据访问类,类名为CData。定义连接Oracle数据库的方法ConnOracle,获取数据集的方法GetDataSet,获取物理表的方法GetDataTable,向物理表中插入一行数据的方法Insert,向物理表中删除数据的方法Delete,向物理表中更新数据的方法Update。其实现方法不是本文的重点,在此仅给出代码,不作详细分析。代码如下: 财管家 园 fs119.net

PublicClassCDataBase
DimOleCnnDBAsNewOleDbConnection()

'连接Oracle数据库,ServerName:服务器名,UserId:用户名,UserPwd:用户密码
PublicFunctionConnOracle(ByValServerNameAsString,ByValUserIdAsString,ByValUserPwdAsString)AsOleDbConnection

 DimOleCnnDBAsNewOleDbConnection()
 WithOleCnnDB
  .ConnectionString="Provider=MSDAORA.1;Password='"&UserPwd&"';UserID='"&UserId&"';DataSource='"&ServerName&"'"
  Try
   .Open()
  CatcherAsException
   MsgBox(er.ToString)
  EndTry
 EndWith
 mOleCnnDB=OleCnnDB
 ReturnOleCnnDB
EndFunction

'获取数据集。TableName:表名,strWhere:条件
PublicOverloadsFunctionGetDataSet(ByValTableNameAsString,ByValstrWhereAsString)AsDataSet

 DimstrSqlAsString
 DimmyDataSetAsNewDataSet()
 DimmyOleDataAdapterAsNewOleDbDataAdapter()

 myOleDataAdapter.TableMappings.Add(TableName,TableName) 财管,家园,fs119.net
 strSql="SELECT*FROM"&TableName&"where"&strWhere

 myOleDataAdapter.SelectCommand=NewOleDbCommand(strSql,mOleCnnDB)
 Try
  myOleDataAdapter.Fill(myDataSet)
 CatcherAsException
  MsgBox(er.ToString)
 EndTry
 ReturnmyDataSet
EndFunction

'获取物理表。TableName:表名
PublicOverloadsFunctionGetDataTable(ByValTableNameAsString)AsDataTable
 DimmyDataSetAsNewDataSet()
 myDataSet=GetDataSet(TableName)
 ReturnmyDataSet.Tables(0)
EndFunction

'获取物理表。TableName:表名,strWhere:条件
PublicOverloadsFunctionGetDataTable(ByValTableNameAsString,ByValstrWhereAsString)AsDataTable

 DimmyDataSetAsNewDataSet()
 myDataSet=GetDataSet(TableName,strWhere)
 ReturnmyDataSet.Tables(0)
EndFunction

 '向物理表中插入一行数据。TableName:表名,Value:行数据,BeginColumnIndex:开始列
PublicOverloadsFunctionInsert(ByValTableNameAsString,ByValValueAsObject,OptionalByValBeginColumnIndexAsInt16=0)AsBoolean 财管家.园.fs119.net

 DimmyDataAdapterAsNewOleDbDataAdapter()
 DimstrSqlAsString
 DimmyDataSetAsNewDataSet()
 DimdRowAsDataRow
 Dimi,lenAsInt16

 strSql="SELECT*FROM"&TableName
 myDataAdapter.SelectCommand=NewOleDbCommand(strSql,mOleCnnDB)
 DimcustCBAsOleDbCommandBuilder=NewOleDbCommandBuilder(myDataAdapter)
 myDataSet.Tables.Add(TableName)
 myDataAdapter.Fill(myDataSet,TableName)
 dRow=myDataSet.Tables(TableName).NewRow
 len=Value.Length
 Fori=BeginColumnIndexTolen-1
  IfNot(IsDBNull(Value(i))OrIsNothing(Value(i)))Then
   dRow.Item(i)=Value(i)
  EndIf
 Next
 myDataSet.Tables(TableName).Rows.Add(dRow)
 Try
  myDataAdapter.Update(myDataSet,TableName)
 CatcherAsException
  MsgBox(er.ToString)
  ReturnFalse
 EndTry
 myDataSet.Tables.Remove(TableName)
 ReturnTrue
EndFunction

'更新物理表的一个字段的值。strSql:查询语句,FieldName_Value:字段及与对应的值
财管 家园 fs119.net

PublicOverloadsSubUpdate(ByValstrSqlAsString,ByValFieldName_ValueAsString)

 DimmyDataAdapterAsNewOleDbDataAdapter()
 DimmyDataSetAsNewDataSet()
 DimdRowAsDataRow
 DimTableName,FieldNameAsString
 DimValueAsObject
 Dima()AsString

 a=strSql.Split("")
 TableName=a(3)
 a=FieldName_Value.Split("=")
 FieldName=a(0).Trim
 Value=a(1)
 myDataAdapter.SelectCommand=NewOleDbCommand(strSql,mOleCnnDB)
 DimcustCBAsOleDbCommandBuilder=NewOleDbCommandBuilder(myDataAdapter)
 myDataSet.Tables.Add(TableName)
 myDataAdapter.Fill(myDataSet,TableName)
 dRow=myDataSet.Tables(TableName).Rows(0)
 IfValue<>NothingThen
  dRow.Item(FieldName)=Value
 EndIf
 Try
  myDataAdapter.Update(myDataSet,TableName)
  myDataSet.Tables.Remove(TableName)
 CatcherAsException
  MsgBox(er.ToString)
 EndTry
EndSub

'删除物理表的数据。TableName:表名,strWhere:条件
PublicOverloadsSubDelete(ByValTableNameAsString,ByValstrWhereAsString)
财,管家园,fs119.net

 DimmyReaderAsOleDbDataReader
 DimmyCommandAsNewOleDbCommand()
 DimstrSqlAsString
 strSql="deleteFROM"&TableName&"where"&strWhere
 myCommand.Connection=mOleCnnDB
 myCommand.CommandText=strSql
 Try
  myReader=myCommand.ExecuteReader()
  myReader.Close()
 CatcherAsException
  MsgBox(er.ToString)
 EndTry
EndSub
EndClass


财软联.盟.fs119.net

财.软联盟.fs119.net

财软联.盟.fs119.net


财,软联盟,fs119.net

财,软联盟,fs119.net

  定义一操作数据库中物理表的类CData,此类继承CDataBase,即:

财软,联盟,fs119.net

PublicClassCData:InheritsCDataBase
  此类应该由供用户提供所操作的物理表的表名,指定了表名就可取得该表的所有性质。该表主要完成插入、删除、更新功能。定义其属性、方法如下:

  申明类CData的变量:

'所要操作的表名
PrivateSharedUpdateTableNameAsString
'所要操作的表对象
PublicSharedUpdateDataTableAsNewDataTable()
'对应表的一行数据197
PublicSharedObjFields()AsObject
'表的字段数
PublicSharedFieldCountAsInt16
'主关键字。我们假设每个物理表都有一个主关键字字段fSystemID
PublicSharedSystemIDAsString
  说明:Shared关键字指示一个或多个被声明的编程元素将被共享。共享元素不关联于某类或结构的特定实例。可以通过使用类名或结构名称或者类或结构的特定实例的变量名称限定共享元素来访问它们。
财,管家园,fs119.net


  申明类CData的属性UpdateTable,当向UpdateTable赋给了一个已知表的表名,就可确定表的字段数,定义出数据行。这里,先打开表,再重新定义数据行.

PublicPropertyUpdateTable()AsString
 Get
  UpdateTable=UpdateTableName
 EndGet
 Set(ByValValueAsString)
  UpdateTableName=Value.Trim
  UpdateDataTable=DB.GetDataTable(UpdateTableName)
  UpdateTableFieldNames=UpdateDataTable.Clone
  FieldCount=UpdateDataTable.Columns.Count
  ReDimObjFields(FieldCount-1)
 EndSet
EndProperty

'删除由主关键值fSystemID指定的数据行
PublicSubDelete()
 DimstrSQLAsString

 strSQL="Deletefrom"&UpdateTableName&"wherefSystemID="&SystemID
 DB.Delete(strSQL)
 UpdateDataTable.Rows.Remove(GetRow)
EndSub

'向表UpdateTableName中插入一行数据。数据由ObjFields给出
PublicFunctionInsert()AsBoolean 财管家,园,fs119.net
 DB.Insert(UpdateTableName,ObjFields)
EndFunction

'更新表UpdateTableName所指定的行
PublicShadowsSubUpdate()
 DimSetFieldAsString
 DimiAsInt16

 Fori=1ToFieldCount-1
  SetField=UpdateTableFieldNames.Columns(i).ColumnName&"="&ObjFields(i)
  UpdateField(SetField)
 Next
EndSub

PublicSubUpdateField(ByValSetFieldAsString)
 DimStrSQLAsString
 StrSQL="select*from"&UpdateTableName&"wherefSystemID="&SystemID
 DB.Update(StrSQL,SetField)
EndSub

'填充网络数据
PublicOverloadsSubFillGrid(ByValGridNameAsDataGrid)
 GridName.DataSource=UpdateDataTable
EndSub

'把数据网格的当前行数据定写入到输入控件中
PublicSubDataGridToText(ByValfrmAsForm)
 DimRowIndex,iAsInt16
 Dimvalue
 DimobjAsControl
 DimDataGridAsNewDataGrid()
 IfFieldCount=0ThenExitSub
  ForEachobjInfrm.Controls
   Ifobj.GetType.Name="DataGrid"Then
    DataGrid=obj

财管家,园,fs119.net


    ExitFor
   EndIf
  Next
  RowIndex=DataGrid.CurrentRowIndex
  Fori=1ToFieldCount-1
   value=DataGrid.Item(RowIndex,i)
   IfIsDBNull(value)=TrueThen
    value=""
   EndIf
   ForEachobjInfrm.Controls'
    Ifobj.TabIndex=iThen
     obj.Text=value
     ExitFor
    EndIf
   Next
  Next
EndSub


财软,联盟,fs119.net

财,管家园,fs119.net

财软 联盟 fs119.net


财,管家园,fs119.net

财软,联盟,fs119.net

  窗体继承及实现

  所处理的物理表

  有了上面的类,我们就可应用它来实现MIS系统中关于物理表的操作功能。

  例如我们有一个tInfo表、tUser表、tChange表、tSub表,表中都定义了主关键字字段FSYSTEMID,表结构如下:

财.软联盟.fs119.net



        tChange表

tSub表
  生成窗体模板

  我们要向tInfo表、tUser二个表里插入数据,删除数据,更新数据,它们应该分别在二个Form里完成。这里,我们可先定义一Form模板,命名为FrmModule,在FrmModule上增加工具箱ToolBar1,在ToolBar1增加"增加"、"保存"按钮、"删除"、"退出"等按钮,增加数据网络DataGrid1,文本盒及下拉列表盒。布置好后如下图:

财管 家园 fs119.net

  把在继承的Form中可能会重新设置控件的控件对象的友元属性改为公有属性:

  要使模板FrmModule中的控件能够在继承的窗体中能够修改其所继承的控件属性,必须把其友元属性改为公有属性

PublicWithEventsLabel2AsSystem.Windows.Forms.Label
PublicWithEventstxt4AsSystem.Windows.Forms.ComboBox


财管.家园.fs119.net

财管家 园 fs119.net

财管家,园,fs119.net


财软联.盟.fs119.net

财软联盟.fs119.net

  定义FrmModule类的全局变量

  FrmModule直接调用CData类的方法,完成所需功能。

财.管家园.fs119.net

PublicSharedgClsAsNewCData()
PublicgIsUpdateasBoolean
  定义FrmModule的方法

  在FrmModule的Load事件中连接数据库,并填充网格数据,即:

PublicShadowsSubFrmModel_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)HandlesMyBase.Load
 gCls.DB.ConnOracle("GDZC","liyu","123")
 gCls.FillGrid(Me.DataGrid1)
EndSub
  当单击DataGrid1时,应把DataGrid1的当前行写入输入控件中供用户修改数据,取得当前行的标识,这里用SystemID记录,同时表示可以更新。这个过程在DataGrid1的_CurrentCellChanged事件中完成,即:

PrivateSubDataGrid1_CurrentCellChanged(ByValsenderAsObject,ByValeAsSystem.EventArgs) HandlesDataGrid1.CurrentCellChanged
 DimRowIndexAsInt16 财管家.园.fs119.net
 RowIndex=DataGrid1.CurrentRowIndex
 gCls.DataGridToText(Me)
 gCls.SystemID=DataGrid1.Item(RowIndex,0)
 gIsUpdate=True
EndSub
  编写ToolBar1的ButtonClick事件。由按钮文本识别所单击的对象.当时单击"增加"时表示不能更新,当时单击"保存"时要识别是更新还是插入数据。执行完后要重新填充网格,即:

PrivateSubToolBar1_ButtonClick(ByValsenderAsSystem.Object,ByValeAsSystem.Windows.Forms.ToolBarButtonClickEventArgs)HandlesToolBar1.ButtonClick
 SelectCasee.Button.Text
 Case"增加"
  gIsUpdate=False
 Case"保存"
  WriteDateToArray()
  IfgIsUpdateThen
   gCls.Update()
   ExitSelect
  Else
   gCls.Insert()
  EndIf
 Case"删除"
  IfMsgBox("真的删除该数据吗?(Y/N)")=7Then
   Return
  EndIf
  gCls.Delete()
 Case"退出"
财 软联盟 fs119.net

  Me.Close()
  ExitSub
 EndSelect
 gCls.FillGrid(DataGrid1)
EndSub

'把输入的数据用对象数组保存起来
PublicOverridableSubWriteDateToArray()
 DimiAsInt16
 DimobjAsControl
 Fori=1TogCls.FieldCount-1
  ForEachobjInMe.Controls
   Ifobj.TabIndex=iThen
    gCls.ObjFields(i)=obj.Text
    ExitFor
   EndIf
  Next
 Next
 gCls.ObjFields(0)=gCls.DB.GetMaxID(gCls.UpdateTable,"FSYSTEMID")1
EndSub


财.管家园.fs119.net

财软.联盟.fs119.net

财,管家园,fs119.net


财管家园.fs119.net

财软联盟 fs119.net

  生成继承窗体

  生成继承窗体

  我们的编程工作大部分都完成了,现在只需要增加新的继承窗体Form就可,方法是在Form项或项目菜单或工具栏选择添加继承的窗体,在弹出的Form中输入窗体名frmUser按打开,在选择继承器中选择FrmModule确定就生成了一新的窗体。继承的继承如下:

财软联盟 fs119.net

PublicClassfrmUser:InheritsfrmModel
  在生成的窗体中增加一些必要的控件,同时与根据表中字段对应关系设置的TabIndex的值。

  通过设置控件TabIndex的值,可以把该控件与物理表中的字段关系对应起来,如TabIndex为1,则对应物理表的第1个字段,如TabIndex为2,则对应物理表的第2个字段,如此例推。这方便把输入控件的数据写入表中,把网格数据写入输入控件中,这是技巧,其实现过程见方法:WriteDateToArray(),DataGridToText()。

  指定物理表

  在类frmUser的New方法中指定所操作的物理表名tUser。为什么要在这里指定表名呢?是因为程序在调用frmUser前,先必须申请frmUser的实类,同时进行实类化,自动执行构造函数New(),执行New()时,就把我们所要完成的功能代码放在这里,让它们自动执行。 财软联盟,fs119.net

PublicSubNew()
 MyBase.New()
 '该调用是Windows窗体设计器所必需的。
 InitializeComponent()
 gCls.UpdateTable="tUser"
 '在InitializeComponent()调用之后添加任何初始化
EndSub

  更改控件的属性,隐藏不需要的控件

  在frmUser的Load事件中更改DataGrid1的标题并隐藏不需要的控件:

PrivateSubfrmUser_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)Handles MyBase.Load
 DataGrid1.CaptionText="用户列表"
 cbo.Visible=False
 Me.Label6.Visible=False
EndSub
  按同样方法,生成下面的窗体frmInfo,在此窗体上增加一些新控件,如下:

财软联.盟.fs119.net

  窗体frmInfo类继承frmModel:

PublicClassfrmInfo:InheritsfrmModel
在类frmInfo的New方法中指定所操作的物理表名tInfo。
PublicSubNew()
 …
 gCls.UpdateTable="tInfo"
EndSub
  现在,ToolBar1上增加了新的方法"导入",应该怎样处理呢?事实上只要在frmInfo的ToolBar1_ButtonClick事件中识别时"导入",写要处理的任务就可,如下:

PrivateSubToolBar1_ButtonClick(ByValsenderAsSystem.Object,ByValeAsSystem.Windows.Forms.ToolBarButtonClickEventArgs)HandlesToolBar1.ButtonClick
 SelectCasee.Button.Text
 Case"导入"
  …
 EndSelect
EndSub


  通过上面的窗体继承方法,凡是对物理表的操作都可以通过这些方法来完成,而不必再重复编写代码。

财软,联盟,fs119.net

财软联盟,fs119.net

财软 联盟 fs119.net

财软 联盟 fs119.net


财,软联盟,fs119.net

财管家,园,fs119.net

  新的要求

  现在假设有物理表tChange与tInfo表是一关联表,通过关键字段fID关联,既表tChange的字段fID的数据是通过tInfo表提供,其它来源于用户的输入,要生成tChange表数据处理的窗体。要实现这些功能,我们同样通过窗体的继承来完成(有物理表tSub也如此)。

  .先定义窗体模板frmModul2,此frmModul2继承frmModul,即:PublicClassfrmModul2:InheritsAsset.frmModel。在frmModul2中加入列表盒控制ListBox1和其它控制,布置好后如下图:

财软联盟,fs119.net



  .在frmModul2的Load事件中填充ListBox的数据并隐藏不必要的控件。

财软联盟 fs119.net


PrivateSubfrmModul2_Load(ByValsenderAsSystem.Object,ByValeAsSystem.EventArgs)Handles MyBase.Load
 FillListBox(Me.ListBox1)
 Me.tlbAdd.Visible=False
EndSubPublic

SubFillListBox(ByValListBoxAsListBox)
 DimStrSQLAsString
 StrSQL="selectDistinctfID||''||fNameasaFROMtInfo"
 DimdrAsOleDb.OleDbDataReader

 dr=DB.SQLDataReader(StrSQL)
 Whiledr.Read
  ListBox.Items.Add(dr.Item("a"))
 EndWhile
 dr.Close()
EndSub

.当单击ListBox1时选择当前数据并填充至txt1,txt3中
PublicOverridableSubListBox1_MouseDown(ByValsenderAsObject,ByValeAsSystem.Windows.Forms.MouseEventArgs)HandlesListBox1.MouseDown
 Dimi,txt
 i=ListBox1.SelectedIndex
 txt=ListBox1.Items(i)
 txt1.Text=txt.Substring(0,15)
 txt3.Text=txt.Substring(16,Len(txt)-16).trim
 txtID.Text=gCls.GetMaxSystemID1
 gCls.FillGrid(DataGrid1)
 gIsUpdate=False
EndSub 财软联盟.fs119.net

财 管家园 fs119.net

财.软联盟.fs119.net

财管家园.fs119.net


财管 家园 fs119.net

财软联 盟 fs119.net

  好了,我们的窗体模板又做好了,下面我们通过窗体模板frmModul2生成继承窗体frmChange,即:

财管.家园.fs119.net


PublicClassfrmChange:InheritsAsset.frmModul2

  生成的窗体如下图:

财软联 盟 fs119.net



  依照前面设置所操作的表tChange和其它,不必写其它代码。

财管家园 fs119.net


PublicSubNew()

gCls.UpdateTable="tChange"
EndSub

  同样可生成操作表tSub的窗体frmSub。

财 软联盟 fs119.net




  总结

  通过以上面事例的介绍,可以生成若干同类似的窗体。不论操作多少表,都可通过窗体继承得到,物理表的操作一次性完成,不必在每个窗体中写代码,所完成的功能及界面布局全在模板窗体中完成。这样极大地降低了编写代码的工作量,同时为设置窗体整体外观提供以方便,提高了开发效率,也降低了软件的测试和维护的工作量。继承是面向对象的开发语言的一个重要组成部分,在程序设计中充分的利用继承关系,可以最大范围的提高程序的可利用性,使得用最少的代码开发比较大的应用程序。
财软联盟,fs119.net

财软联 盟 fs119.net

财软.联盟.fs119.net


上一篇:VisualBasic.NET实现后台处理
下一篇:VisualBasic.NET中操作MsAgent

精品课程推荐