单人写管理程序的不成熟的方法

damocles 2006-04-03 10:24:11
单人写数据库管理程序
一天,我老大突发奇想,要我写出一个固定资产的管理系统,把以前手工管理改为全微机化管理。(也不知道有没有奖金)没有办法,只有写了。根据以往的经验,知道这个程序可大可小的,为了保险起见,我要了2个月的时间。

第一部,分析
老板走后,马上问办公室要了全套的报表 :

1>固定资产登记卡 :
编号|资产名|类别|型号|生产厂家|单位|数量|原价值|使用日期|使用单位|报管人|登记日期
其中附属设备:
|名称|数量|单位|单价|总价|

2>异动记录表
|异动时间|异动依据|调出单位|调入单位|经办人|

3>修理记录表
|修理日期|修理范围类别|承修单位|修理费用|


4>固定资产汇总表
|部门|
|资产类别|数量|价值|其中正常数量|价值|其中注销|价值|

看起来应该是不复杂的,数据流程也很简单(我没有学过正规的系统分析那一套东西,一起都凭经验^_^),应该从录入卡片开始,资产注销结束。中间需要一些表记录如异动,注销,修理这些历史信息。从表1看来很明显需要两个表记录数据,“卡片表”-<“附属设备表”,他门应该为一对多关系,“异动记录”,“修理记录”,各许要建立一个表,为“卡片表”记录数据库操作历史信息,相当于系统的日志,为了更完善,另外还应该加入记录“注销记录”,这个表,例外还应该加上记录用户和全限的表,系统应该就可以初步使用了;其他的东西可以先放一下,先看看库表是设计。
数据库服务器选用我最喜欢的ms sql 作为数据库服务器,ms sql和vb兼容特别好(当然了,一个公司出品的麻),支持viwe,事务,级联等,可以很容易的开发出对多用户的版本,而且维护方便。在设计比较大型的数据库的时候推荐使用。
库表的设计
为了安全起见,我把记录数据和记录权限的表分为两个数据库,OFFICE_db用来记录数据,System_Db用来记录权限,然后在这个数据库之下建立表,我了以后维护方便,命名时后我尽量用中文。(坏习惯,大家不要学)

最先是卡片记录,除了卡片上的信息外,应该加入一个主键code_id,当然还应该加入 “注销标志”和“修理标记”两个字段以记录当时卡片的状态。

卡片信息表:code
code_id| cname| 类型| 型号| 产地| 资金来源| 使用日期| 价值| 使用单位| 存放地|使用年限| 录入员| 验收日期| 注销标志| 修理标记| 保管人|编号id| 登记日期

然后是附属资产表:code_mx
mx_id|code_id|c_name|单位|单价|型号|备注

注意,每个表都应该有他的主键,所以增加一个字段mx_id as bigint,把它的标识位设置为“是”,这样就可以不用管它了,以后如果没有特殊说明,都这样设置,它会自动递增的(不懂ms sql的自己去看ms sql 的帮助文件)。由于本表和code表为一对多的关系,应该增加字段code_id,并且建立 code.code_id-<code_mx,code_id的关系,设置的时候应该在“对复制强行关系”、“对insert于uodate 强制关系 ”、“级联更新”、“级联删除” 这几个选项上打上勾,这样设置了级联以后,只要删除或者更新主表数据,从表中的相关数据会自动更新或者删除,怎么样,方便把,以后的主从表没有特别的说明都这样设置。

现在已经设计出两个表了(“好有成就感”)但我再次审视的时候发现一个问题,| 类型|使用单位|两个字段明显臃于了,每次都要输入同样的信息,应该改进。于是我把这个表分为3个。

卡片信息表:code
code_id| cname| 类型_id| 型号| 产地| 资金来源| 使用日期| 价值| 使用单位_id| 存放地|使用年限| 录入员| 验收日期| 注销标志| 修理标记| 保管人| 审核标记|编号id| 登记日期

使用单位:使用单位_dic
部门id| 单位id| 部门名称| 负责人| 部门属性|电话|备注

类型:类型_dic
类型id|name| 使用年限| 备注


这三个表之间也互为主从 : 使用单位_dic code.单位id-< code.单位id
类型_dic code.类型id -< code.类型id


这两个表用了后缀名dic ,表明他们是字典表,养车统一的命名习惯是很重要的,这点要主意。

然后设置日志表:我习惯用log作为后缀名


异动记录:异动_log
异动_id|code_id| code_name| 转移日期| 异动原因| 原单位| 原部门| 原存放地| 现单位| 现部门| 现在存放地| 操作员| 异动性质| 备注

修理记录:修理_log
修理_id| code_id| 开始日期| 结束日期| 修理原因| 操作员| 备注

注销记录:报废_log
注销_id| code_id| 报废日期| 原金额| 减少类型| 报废原因| 操作员| 备注


这几个表之间也设置为主从 :

code.code_id-<异动_log.code_id
code.code_id-<修理_log.code_id
code.code_id-<报废_log.code_id

现在OFFICE_db库基本建立完成,在建立system_db之前,应该先想想权限的设置

考虑权限应该有以下权限的设置 录入, 异动, 报废, 审核, 修改, 删除, 数据字典, Manager(管理员)

权限种类很多阿^_^,如果直接设置在用户身上,管理会很麻烦的阿.想想WINDOWS中的权限设置把,于是有了注意.

权限>-用户组->用户

这样管理起来就方便多了,如果要增加用户,只要把它加入相应的主就可以了,不用在给他负那么多的权限了.

表这样设计

用户组记录表: user_type
user_type, type_name, 录入, 异动, 报废, 审核, 修改, 删除, 数据字典, Manager
其中 录入,异动 这些权限字段全部是int形的 1为有权限,0为没有相应的权限.

用户记录表: user
user_id, user_name, user_type, passwd, 注销标记, 备注

设置关联 user_type.user_type, -< user.user_type,

当然还有用户的登陆历史记录:logo_h
logo_id, user_id, user_name, logo_date, logout_date

logo_date是记录登陆时间,logout_date是记录退出时间.这个表也设置关联 user.user_id-<logo_h.user_id

OK现在数据结构基本告一段落了
...全文
85 点赞 收藏 1
写回复
1 条回复
damocles 2006年04月03日
代码设计

哈哈,可以正式的设计程序了.什么???需求分析还没有完?这个就只有抱歉了,我没有学过系统分析啊!现在开始来写代码把,我把程序大体上分为了三个部分,登录窗口-主程序-打印程序,先从登录窗口开始做把.,打开vb ,新建立一个工程,把from1改名为logo_frm,放上两个text控件,改名字为Txt_pwd,和Txt_user ,看名字就知道意思了把, 然后在添加一个cmd 控件,改名为cmd_yes,可以了,先这样测试一下


Private Sub cmd_yes_Click()
Dim rcd_tmp As New ADODB.Recordset
Dim comm_tmp As New ADODB.Command
Dim conn_sys As New ADODB.Connection

conn_sys.open "Provider=SQLOLEDB.1;Password= ;Persist Security Info=True;User ID=sa;Initial Catalog=system_db;Data Source=server ;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=sa;Use Encryption for Data=False;Tag with column collation when possible=False"'连接数据库

comm_tmp.ActiveConnection = conn_sys
comm_tmp.CommandType = adCmdText
comm_tmp.CommandText = "select * from [user] where user_name= " & Txt_user
Set rcd_tmp = comm_tmp.Execute
Date = DTP_login.Value

If Txt_pwd = pwd(rcd_tmp.Fields("passwd")) Then
msgbox "yes"
Unload Me
Else
Txt_pwd = ""
Label5.Caption = ">>密码输入出错"
Txt_pwd.SetFocus
End If
End Sub

很简单,通过了,有点得意啊.不过只是个实验啊,还需要大量的改进,着个代码有个关键性的错误,就是用户记录表的主键是user_id,用" where user_name= " & Txt_user查询可能会预见同名同姓的人,那么就会返回两个记录,势必会造成错误.必须用user_id 来查询,改进一下,把Txt_user换成cobmoBox控件,让用户在登录的时候自动选择,就像以前win98的友好登录一样.方便使用是我写程序的宗旨啊,哈哈.删除Txt_user,添加个cobmoBox控件,改名为cbm_user,在Form_Load中添加初始化代码.
先把共用的数据库初始化的代码分离出来
设置共有变量
Dim rcd_tmp As New ADODB.Recordset
Dim comm_tmp As New ADODB.Command
Dim conn_sys As New ADODB.Connection
Dim user_str() As String'这个用来存放 user_id
设置数据库初始化函数
Private Sub Logo_SysDb()
conn_sys.open "Provider=SQLOLEDB.1;Password= ;Persist Security Info=True;User ID=sa;Initial Catalog=system_db;Data Source=server ;Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=sa;Use Encryption for Data=False;Tag with column collation when possible=False"'连接数据库
comm_tmp.ActiveConnection = conn_sys
comm_tmp.CommandType = adCmdText
end sub

然后是系统初始化
Private Sub Form_Load()
Dim i As Long
Dim Count_data(2) As Long
Dim LOG_STR As String
Logo_SysDb '初始化数据驱动
rcd_tmp.Open "select * from [v_user] where 注销标记 =0", conn_sys, adOpenKeyset, adLockOptimistic
Count_data(1) = rcd_tmp.RecordCount '得到行数
ReDim user_str(Count_data(1)) As String '公用数组存放 user_name 字段
Cbm_user.Clear

For i = 1 To Count_data(1)
Cbm_user.AddItem rcd_tmp("user_name").Value
user_str(i) = rcd_tmp("user_id").Value '公用数组存放 user_name 字段
rcd_tmp.MoveNext
Next
Cbm_user.ListIndex = 0
End Sub

这样就比刚才要好的多了,user_id存放在user_str()中 ,用user_str(Cbm_user.ListIndex + 1)就可以读出了,然后这个还是不够好,conn_sys.open 的连接字符串被设定死了,没法动态设置数据库服务器和用户密码,这样很不好.应该用一个配置文件来记录 数据库服务器,用户秘密.我在程序目录下新建立一个文件 main.ini ,内容设置为
[login]
dbserver=server
passwd=
然后添加一个模块,添加个函数
Public Function myReadINI(path, inisection, inikey, iniDefault)
path 为 ini 文件的路径
inisection 为条款名称
inikey 条目名称
iniDefault 返回值
如:
pwd_str = myReadINI(App.Path & "\main.ini", "login", "passwd", pwd_str)

用于读写ini文件,具体内容就不多说了,我都是上网down下来的

现在修改Logo_SysDb()为


Private Sub Logo_SysDb()
Dim pwd_str As String
Dim server_str As String
pwd_str = myReadINI(App.Path & "\main.ini", "login", "passwd", pwd_str)
server_str = myReadINI(App.Path & "\main.ini", "login", "dbserver", server_str)
pwd_str = Left(Trim(pwd_str), Len(Trim(pwd_str)) - 1)'去掉最后的会车
server_str=Left(Trim( server_str), Len(Trim( server_str)) - 1)

conn_sys.open "Provider=SQLOLEDB.1;Password= " + pwd_str+ " ;Persist Security Info=True;User ID=sa;Initial Catalog=" & data_str & ";Data Source= " & server_str & ";Use Procedure for Prepare=1;Auto Translate=True;Packet Size=4096;Workstation ID=" & server_str & ";Use Encryption for Data=False;Tag with column collation when possible=False"
连接数据库

comm_tmp.ActiveConnection = conn_sys
comm_tmp.CommandType = adCmdText
End Sub

ok测试通过了
还有事情要做,就是记录登录用户的基本信息
先在公用模块中 设置个自定义对象

Type usr_my
name as string
group as string
录入 As Long
异动 As Long
报废 As Long
修改 As Long
审核 As Long
数据字典 As Long
删除 As Long
Manager As Long
logdate as date ,这个是记录登录时间的
End Type
Public main_usr as usr_my '全局变量我习惯在前面加 main字符串,统一格式.
现在需要建立视图

在cmd_yes_Click中把用户信息记录在 main_usr中
Private Sub cmd_yes_Click()
comm_tmp.CommandText = "select user_type.*,user.* from [user] ,user_type where user_type.user_type=user.user_type and user.user_id =" & user_str(Cbm_user.ListIndex + 1)
Set rcd_tmp = comm_tmp.Execute

If Txt_pwd = pwd(rcd_tmp.Fields("passwd")) Then
jl_logo (rcd_tmp("user_id"))

logdate as date ,这个是记录登录时间的
'------------就是这里------------
main_usr.name =rcd_tmp("user_name")
main_usr.group=rcd_tmp("user_type")
main_usr.录入 =rcd_tmp("录入 ")
main_usr.异动=rcd_tmp("异动")
main_usr.报废=rcd_tmp("报废")
main_usr.审核=rcd_tmp("审核")
main_usr.修改=rcd_tmp("修改")
main_usr.删除=rcd_tmp("删除")
main_usr.数据字典=rcd_tmp("数据字典")
main_usr.Manager=rcd_tmp("Manager")
msgbox ("连接成功,在这里录入加载主窗口的代码")
Unload Me
Else
Txt_pwd = ""
Label5.Caption = ">>密码输入出错"
Txt_pwd.SetFocus
End If
End Sub

这才像话嘛,就要结束了,现在是收尾工程,要想这个程序好看和实用,还需要一些功夫.添加一些label控件,用来说明各个输入框的作用由于有时需要补录以前的数据,应该包含修改系统时间的功能.添加个DTPpicker ,然后在cmd_yes_Click中添加
Date = DTP_login.Value
在from_land中添加
DTP_login.Value=date
就ok了

在界面上建立一个Label让它显示当前所选择用户 的权限,这个应该很简单把,我就不多说了

还要新建个退出按钮cmd_no用于退出程序
Private Sub cmd_no_Click()
Unload Me
End Sub
ok,现在终于像个程序了,别忘记了把各个控件都排列整齐,怎么样,漂亮的登录框


现在只是完成了程序的一点点,我用的边写边改的分析方法是为正规学院派所不齿的,但是我这只是一种思路,希望给初学者有所帮助
回复 点赞
发动态
发帖子
非技术类
创建于2007-09-28

610

社区成员

2.7w+

社区内容

VB 版八卦、闲侃,联络感情地盘,禁广告帖、作业帖
社区公告
暂无公告