阅读:1535回复:1
用VB动态生成不同使用权限的菜单
<TABLE width=620 align=center>
<TR> <TD class=a14>在笔者开发的一个多用户协同工作的软件中,多个用户需共用一窗体及其上的菜单,但不同级别的用户对菜单的使用权限是不同的,而用户的组成与身份都是动态的,为此,笔者开发了一个程序,让管理员以可视化的方式在用户初次登录时分配该用户可用的菜单项,来控制用户的使用权限,所以用户可以根据登录时分配的权限使用菜单不同的选项。本文以产品结构管理系统为例,介绍一下具体的工作。</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14><B>一.数据库的设计及介绍</B></TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>该程序需要三个数据库表的支持。用户的注册信息在t_register表中存放,表t_privilege用来存储用户的别名和它可用菜单项的名称和代号,而把窗口上的所有菜单项放在一个叫t_menu的表中。三个表的结构和说明如下:</TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14><IMG src="http://www.ccw.com.cn/htm/app/aprog/01_7_12_3a.gif"> </TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>name字段表示用户的真实名字,password字段表示用户的密码,nickname字段表示用户的别名,别名的使用是为了防止用户的重名,别名应该是唯一的。</TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14><IMG src="http://www.ccw.com.cn/htm/app/aprog/01_7_12_3b.gif"> </TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>nickname字段表示用户的别名,usemenuname表示菜单项的名称 ,usemenu表示菜单项的标题,id字段表示此菜单项在表t_menu中的id号。</TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14><IMG src="http://www.ccw.com.cn/htm/app/aprog/01_7_12_3c.gif"> </TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>id字段表示菜单项的记录号,mcaption字段表示菜单项的标题 ,mname字段表示菜单项的名称。举例来说,在笔者开发的软件中,应用界面的菜单有5项,标题分别为文件、编辑、系统维护、窗口、帮助,名称为mnumain,索引值为0,1,2,3,4。数组n(0),n(1),n(2),n(3),n(4)分别代表这5项应用界面菜单各包含的子菜单数。它们的子菜单名称分别为mnufile,mnuedit,mnuwh,mnuwindow,mnuhelp,不同的子菜单各设置不相干扰的的索引值。例如:在“文件”菜单项下的”打开”子菜单项,名称为mnufile,索引值为0,”退出”子菜单项,名称为mnufile,索引值为2,在“编辑”菜单项下的”产品结构展开”子菜单项名称为mnuedit,索引值为0。</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14><B>二.工作流程</B></TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>用户第一次注册后,管理员设置用户可用的菜单项,设置的界面如图1。左边组合框1列出t_register表中已注册的所有用户别名,列表框2列出表t_menu中name字段的内容,即应用界面菜单中所有的菜单项。管理员可以在组合框1中选择用户,然后在列表框2中选择该用户可用的菜单项,选中的菜单项被移到列表框3中。如果选择了不需要的菜单项,则双击列表框3中的已选项使其还原到列表框2中。按完成按钮后,用户别名和该用户可用的菜单项的名称、标题和其在t_menu表中的id号分别被存入表t_privilege中的nickname、usemenu、usemenuname和id字段。</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>用户设置完成之后,已注册的用户可以登录了。用户输入别名和密码后,用表t_register进行验证,通过后,从表t_privilege中找出与此用户别名相同的所有记录中usemenuname字段中的值记录的值,即找到可用的菜单项。再把这些可用项在应用界面的菜单中的的Enable属性设置为True(缺省为False)。</TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14 height=14><IMG src="http://www.ccw.com.cn/htm/app/aprog/01_7_12_3d.jpg"> </TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14>图1 设置用户菜单</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>对已分配菜单使用权限的用户,登录后,系统处理给该用户的菜单功能的分配。这里,定义了一个记录集myrs,myrs为t_privilege表中nickname字段的值等于输入用户别名的所有记录。笔者先在模块中定义一个Init函数,它根据菜单各菜单项的数量设置的数组个数,而数组的值是每一个菜单项的子菜单项个数,这样子菜单中的项可以任意的添加,只需改动数组的值。在本文的例子里,设置如下:</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Public Function init()</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>……</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>c=5 ‘c为应用界面菜单中的菜单项个数</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>n(0) = 3</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>n(1) = 4</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>n(2) = 3</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>n(3) = 4</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>n(4) = 2</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>m(0) = n(0) ‘数组m(i)是第i子菜单项与第0,1,i-1子菜单项的个数和</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>For i = 1 To c – 1 </TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>m(i) = m(i - 1) + n(i)</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Next</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>End Function</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14></TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>然后,处理菜单的具体程序如下:</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>…… </TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Set myrs = New ADODB.Recordset</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>……</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>‘菜单处理</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>myrs.Open "select * from t_privilege where nickname='" ; nickname ; "'", cnn2, adOpenDynamic, adLockBatchOptimistic ‘用只读方式打开t_privilege表中的 nickname字段中等于输入别名的所有记录 </TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>‘用只读方式打开t_menu表</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>k = myrs.RecordCount ‘k为打开的记录数目</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Init ‘Init 为初始化数组的函数</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>For i = 1 To k</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>t = myrs ("id") ‘t为匹配记录的记录号</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>‘下面为t所在记录的菜单项索引值,找到所它所连接的菜单项后,把其enable属性设为True,即此菜单项为可用</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>If t > m(4) Then</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>MsgBox "出现错误 !"</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>ElseIf t > m(3) Then</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>j = t - m(3)</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Form1.mnuhelp.Item(j - 1).Enabled = True</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>ElseIf t > m(2) Then</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>j = t - m(2)</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Form1.mnuwindow.Item(j - 1).Enabled = True</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>ElseIf t > m(1) Then</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>j = t - m(1)</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Form1.mnuwh.Item(j - 1).Enabled = True</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>ElseIf t > m(0) Then</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>j = t - m(0)</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Form1.mnuedit.Item(j - 1).Enabled = True</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Else: j = t</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Form1.mnufile.Item(j - 1).Enabled = True</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14></TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>End If</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>myrs.MoveNext</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>Next</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>……</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14></TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14><B>三.效果图</B></TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>在应用界面的菜单中,选定的菜单项为可见,其余没有选定的菜单项为不可见。用户“湘湖”登录以后,其中“打开”、“重新登录”、“退出”、“XML文档结构展开”、“XML文档编辑”子菜单项在图1中已经选定,在“系统维护”菜单下,“XML文档结构展开”、“XML文档编辑”子菜单项为可用,而“产品结构展开”、“产品结构录入”子菜单项为不可用。因此可以见到如图2的界面:</TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14 height=19><IMG src="http://www.ccw.com.cn/htm/app/aprog/01_7_12_3e.jpg"> </TD></TR></TABLE> <TABLE width=620 align=center> <TR align=middle> <TD class=a14>图2 用户登录后界面</TD></TR></TABLE> <TABLE width=620 align=center> <TR> <TD class=a14>本文所提的方案在WINDOWS 98环境下,通过VB 6.0 和ACCESS 97 调试成功。</TD></TR></TABLE> |
|
|
1楼#
发布于:2005-08-12 23:41
顶
|
|