如何在MS Access中创建用户权限和自定义菜单

很少由数据库设计器为自己和自己构建数据库。 它通常是根据客户的要求构建的。 很多时候,数据库将有多个用户,这些不同的用户可能(也可能不会)在数据库中执行不同的功能。
MS Access使用可以加密数据库(前端和/或后端)以限制谁可以打开数据库的密码来提供一些安全性。 但是,我们仍然面临这样的问题,即用户一旦访问数据库就可以访问,因为密码加密可以解锁整个数据库,而不仅仅是某些部分。
管理多个用户的选项之一是拥有一个可在数据库内执行的总机或活动菜单,并且用户将仅根据其在工作中心中的职责来选择适用于他们的那些项目。 但是,使用此选项的主要挑战是您向用户“探索”他们不应该浏览的数据库位置敞开大门。 在大多数情况下,这并不是真正的问题,因为普通员工不想破坏他们的工作地点。 但是,当涉及到个人,机密甚至医疗信息时,它应该让数据库管理员在其数据库中内置某些保护措施,以确保不受限制的信息不会偶然或偶然地出现。
另一种解决方案是为每种类型的用户创建单独的前端。 当一个用户需要访问一组特定的表单和报表时,可以将这些对象加载到链接到后端的一个前端中。 另一个用户需要一组不同的表单和报告,因此数据库管理员将构建另一个合适的前端。 然而,这种解决方案的明显挑战是不断扩展不同的有限元。 由于某些不同的用户(或不同类型的用户)可能需要使用相同的对象,因此这也可能导致大量的工作重复。 然后,每次更改这些对象之一时,还必须更新包含该对象的所有FE。
我发现自己在工作中心处于这种情况。 我们只有10名定期使用数据库的员工,有时还有10多名在短期内访问非常有限的员工。 但是,这20名员工在数据库中的角色完全不同。 此外,由于我们接触的几乎所有内容都是《隐私法信息》(我在联邦政府工作),因此我们希望尽可能地控制访问权限。
随着时间的推移,我根据用户开发了一种限制对数据库访问的方法。 这样做的方法很简单:
  1. 创建一个用户表
  2. 建立公共常量和变量
  3. 确定谁访问了数据库
  4. 确定如何处理该用户
  5. 允许特定于用户的数据库访问
创建用户表

您的表可能具有不同的字段,但是我的表(tblUsers)根据我的要求具有某些字段。 随意列出自己的需求列表并适当构建表。 我的表的说明如下:
 Field Name      Data Type 
UserKey         Long (AutoNumber)
UserID          Text
UserName        Text
UserRights      Integer
UserMachine     Text
UserDirectory   Text
UserSigBlock    Memo
UserID是从OS环境返回的值,用于标识当前登录到计算机的人员。 我们所有的计算机都需要智能卡访问权限,因此安全性始终是双重身份验证。 只有经过验证的用户才能访问数据库。
下面将解释UserRights,但这是一个值,它指示用户将具有什么访问级别(或访问区域)。 这在最后的步骤中起作用。
由于我们的IT部门经常要求提供用户计算机名称的列表,因此我已将其包括在列表中,并且也可以从OS环境中轻松获得。
有时,我们的用户会从数据库中下载报告或电子表格,拥有用户建立的目录有助于确保他们的项目始终在一个地方。
我们的办公室经常从数据库发送电子邮件,因此我还包括了一个用户可自定义的电子邮件签名块。 这使数据库可以快速将签名块添加到外发电子邮件中。 这很方便。
现在,您的用户表已创建,我们需要弄清楚如何使用它!
建立公共常量和变量

我创建了一个模块,其中包含我的公共变量和公共函数列表,称为modSystem。 以下是我用来限制用户访问权限的列表:
Option Compare Database
Option Explicit 
'User Rights Constants
Public Const UserAdmin As Integer = 1
Public Const UserOIC As Integer = 2
Public Const UserPromo As Integer = 3
Public Const UserRecords As Integer = 4
Public Const UserSrRecorder As Integer = 5
Public Const UserRecorder As Integer = 6 
'User Variables
Public glngCurrentUser As Long
Public gstrUserID As String
Public gstrCurrentUser As String
Public gintUserRights As Integer
Public gstrUserDirectory As String
Public gstrUserMachine As String
我已经为各种类型的用户建立了常量,因为记住用户类型比记住用户权限的值容易。 此外,如果我在整个数据库中使用这些全局常量,并且需要对这些常量的实际值进行任何更改,则无需查找每个“用户权限”实例。 全球常数将解决这一问题。
为了解释我的公共变量,我希望允许数据库始终掌握某些数据。 例如,gstrUserID是从操作系统返回的系统用户ID。 变量gstrCurrentUser是用户的实际名称(例如“ Egbert Schmuckatelli”)。 当数据库管理员设置用户帐户时,将建立此值。 变量glngCurrentUser是tblUsers的主键。 其他变量是不言自明的。
每当我们想将某个用户标识为完成某项任务或必须提供特定于用户的信息时,我都会在整个数据库中使用这些变量。
确定谁访问了数据库

这是最简单的步骤。 当数据库打开时,我使用启动表来自动确定谁登录了数据库以及数据库将对该用户执行的操作。 在表单的OnOpen事件中,我具有以下内容:
Private Sub Form_Open(Cancel As Integer)
On Error GoTo EH
    Dim db As Database
    Dim rst As Recordset
    Dim strSQL As String
    gstrUserID = Environ("USERNAME")
    Set db = CurrentDb()
    strSQL = "SELECT * FROM tblUsers " & _
        "WHERE UserID = '" & gstrUserID & "';"
    Set rst = db.OpenRecordset(strSQL, dbOpenDynaset)
    If Not rst.EOF Then
        With rst
            .MoveFirst
            glngCurrentUser = !UserKey
            gstrCurrentUser = !UserName
            gintUserRights = !UserRights
            gstrUserMachine = !UserMachine
            gstrUserDirectory = !UserDirectory
        End With
    Else
        'This User does not exist in the Users Table
        'Determine what to do--whether to Quit or set up new account
    End If
    rst.Close
    db.Close
    Set rst = Nothing
    Set db = Nothing
    Exit Sub
EH:
    MsgBox "There was an error initializing the Form!  " & _
        "Please contact your Database Administrator.", vbCritical, "Error!"
    Exit Sub
End Sub
因此,在这一点上,数据库知道数据库中用户的权利,但是我们只需要使系统适当地指导它们即可。
确定如何处理用户

由于我的启动表单上没有可操作的对象,因此在后台完成其他操作(由OnTimer事件驱动)后,代码便告诉表单关闭。 在OnClose事件中,我放置了以下内容:
Private Sub Form_Close()
On Error GoTo EH
    Select Case gintUserRights
        Case UserAdmin
            DoCmd.OpenForm "frmAdministrator"
        Case UserPromo, UserOIC, UserSrRecorder
            DoCmd.OpenForm "frmSwitchboard"
        Case UserRecords
            DoCmd.OpenForm "frmCommandRecords"
        Case UserRecorder
            DoCmd.OpenForm "frmPRFReview"
    End Select
    Exit Sub
EH:
    MsgBox "There was an error Closing the Form!  " & _
        "Please contact your Database Administrator.", vbCritical, "Error!"
    Exit Sub
End Sub
您会注意到,根据用户权利,将打开另一个表格。 这对用户是完全透明的,因为我们的“记录”人员仅使用命令记录表。 他们没有什么不同。 记录员无需访问我们的总机,而仅在PRF审核表上执行职责。
但是,您可能会注意到三种不同类型的用户(userPromo,UserOIC和UserSrRecorder)都打开了“配电盘”表单。 这似乎与整篇文章都不相称! 如果您建立了不同级别的用户权限,他们如何才能访问同一表格? 他们不是都可以访问相同的信息吗?
在这里,我对MS Access的经典功能做了一些改动。
允许用户特定的数据库访问

许多年前,Microsoft Access开始引入Switchboard Manager。 我已使用该标准格式作为我的总机的基础,但是进行了一些更改以提供特定于用户的菜单项访问权限。 请记住,如果你目前使用的MS Access'内置的切换面板管理器,此方法将不起作用 ,也不会对你使用内置的切换面板管理器能够编辑的配电盘。 这是对Tables以及运行Switchboard的VBA代码的全面检查,因此您可能希望从头开始。
首先,我对配电盘的基础表进行了一些修改。 我已将表重命名为“ tblSwitchboards”(请注意复数,因为该表实际上保存了多个总机的数据)。 这是我的字段列表:
 Field Name      Data Type 
User            Integer
SwitchboardID   Integer
ItemNumber      Integer
ItemText        Text
Command         Integer
Argument        Text
除了第一个字段(“用户”),我相信该表与自动生成的MS Acces总机表相同。 我要做的一件事是创建一个相关的表tblSwitchboard Commands,该表用作Command字段的行源。 其值如下:
 ID   Command 
0    Page Title
1    Switch Page
3    Open Form
4    Open Report
6    Quit
在数据表视图中查看表格时,这只会使表格更加直观。
此外,我已将参数字段修改为查找字段,其中行源是以下查询:
SELECT MSysObjects.Name
FROM MSysObjects
WHERE (MSysObjects.Type=-32768 OR MSysObjects.Type=-32764)
ORDER BY MSysObjects.Name;
MSysObjects是MS Access中的一个系统表,因此不要四处尝试更改它! 此查询仅返回表单报表名称 ,这是我的用户有权访问的唯一对象( PERIOD! )。 通过一些研究,您可以扩展此查询以包括您想要的任何其他对象。
您可能还注意到,此查询将返回SubForms和SubReports(以及父表单和报表)。 如果你有一个标准的命名规则(因为知道你做......),你可以通过Where子句改变,以进一步限制查询:
WHERE (MSysObjects.Name Like "frm*" AND MSysObjects.Type=-32768) OR (MSysObjects.Name Like "rpt*" AND MSysObjects.Type=-32764)
您可以根据需要进行尽可能多的实验,以获取此查询以返回正确的值列表。
将此字段的“限制到列表”属性设置为“否”非常重要。 其原因很快就会变得显而易见。
现在,我们已经创建了该总机表,让我们对其进行填充。 请原谅这份清单的长度,但我想更详细地说明一下。 请记住,此列表已被大幅削减,但仅用于说明(请原谅那些乱糟糟的列,但在将制表符转换为空格时我没有看到一点):
 User    ID    No.    Item    Cmd    Argument 
Administrator    1    0    ACC Officer Promotions    Page Title    Default
Administrator    1    1    Task Management    Switch Page    2
Administrator    1    2    Administrative Tasks    Switch Page    6
Administrator    1    3    Quit    Quit    
Administrator    2    0    Task Management Menu    Page Title    
Administrator    2    1    Review Open Tasks    Open Form    frmTasks
Administrator    2    2    Overdue Tasks Report    Open Report    rptOverdueTasks
Administrator    2    3    Upcoming Tasks Report    Open Report    rptUpcomingTasks
Administrator    2    4    Task Template    Open Form    frmTaskTemplate
Administrator    2    5    Print Task Template List    Open Report    rptTaskTemplateListing
Administrator    2    6    Print Continuity Book    Open Report    rptContinuityBook
Administrator    2    7    Manage Projects    Open Form    frmProjects
Administrator    2    8    Return to Main Menu    Switch Page    1
Administrator    6    0    Administrative Tasks    Page Title    
Administrator    6    1    Command Records    Switch Page    10
Administrator    6    2    Release Actions    Open Form    frmPromotionRelease
Administrator    6    3    Recorders    Switch Page    11
Administrator    6    4    Evaluation Timeliness    Open Form    frmEvaluations
Administrator    6    5    STEP Quotas    Open Form    frmSTEPQuotas
Administrator    6    6    Manage Users    Open Form    frmUsers
Administrator    6    7    Administrator Functions    Open Form    afrmAdministrator
Administrator    6    8    Return to Main Menu    Switch Page    1
Administrator    10    0    Command Records Menu    Page Title    
Administrator    10    1    Screening Progress    Open Form    frmRecordScreening
Administrator    10    2    Send Missing Evals    Open Form    frmSendMissingEvals
Administrator    10    3    Command Records Database    Open Form    frmCommandRecords
Administrator    10    4    Return to Previous Menu    Switch Page    6
Administrator    11    0    Recorder Actions    Page Title    
Administrator    11    1    Recorder Listing    Open Form    frmRecorders
Administrator    11    2    Recorder Scorecard    Open Form    frmRecorderScorecard
Administrator    11    3    Return to Previous Menu    Switch Page    6
OIC    1    0    ACC Officer Promotions    Page Title    Default
OIC    1    1    Task Management    Switch Page    2
OIC    1    2    Administrative Tasks    Switch Page    6
OIC    1    3    Quit    Quit    
OIC    2    0    Task Management Menu    Page Title    
OIC    2    1    Review Open Tasks    Open Form    frmTasks
OIC    2    2    Overdue Tasks Report    Open Report    rptOverdueTasks
OIC    2    3    Upcoming Tasks Report    Open Report    rptUpcomingTasks
OIC    2    4    Task Template    Open Form    frmTaskTemplate
OIC    2    5    Print Task Template List    Open Report    rptTaskTemplateListing
OIC    2    6    Return to Main Menu    Switch Page    1
OIC    6    0    Administrative Tasks    Page Title    
OIC    6    1    Command Records    Switch Page    10
OIC    6    2    Recorders    Switch Page    11
OIC    6    3    Evaluation Timeliness    Open Form    frmEvaluations
OIC    6    4    Return to Main Menu    Switch Page    1
OIC    10    0    Command Records Menu    Page Title    
OIC    10    1    Screening Progress    Open Form    frmRecordScreening
OIC    10    2    Send Missing Evals    Open Form    frmSendMissingEvals
OIC    10    3    Command Records Database    Open Form    frmCommandRecords
OIC    10    4    Return to Previous Menu    Switch Page    6
OIC    11    0    Recorder Actions    Page Title    
OIC    11    1    Recorder Listing    Open Form    frmRecorders
OIC    11    2    Recorder Scorecard    Open Form    frmRecorderScorecard
OIC    11    3    Return to Previous Menu    Switch Page    6
Officer Promotions    1    0    ACC Officer Promotions    Page Title    Default
Officer Promotions    1    1    Task Management    Switch Page    2
Officer Promotions    1    2    Quit    Quit    
Officer Promotions    2    0    Task Management Menu    Page Title    
Officer Promotions    2    1    Review Open Tasks    Open Form    frmTasks
Officer Promotions    2    2    Overdue Tasks Report    Open Report    rptOverdueTasks
Officer Promotions    2    3    Return to Main Menu    Switch Page    1
Senior Recorder    1    0    Senior Recorder Actions    Page Title    Default
Senior Recorder    1    1    PRF Review    Open Form    frmPRFReview
Senior Recorder    1    2    Recorder Scorecard    Open Form    frmRecorderScorecard
Senior Recorder    1    3    Quit    Quit
注意:“参数”字段可以具有以下四种类型之一:
  1. “默认” –表示这是主配电盘(主页)
  2. 空白–表示这是总机页面标题(也由“命令”字段指示)或表示退出数据库
  3. 一个数字(保存为文本!),指示用户将被定向到的总机页面
  4. 表格或报告的名称
同样,请注意,每种用户类型的“总机”选项明显不同。 现在,我们只需要设置我们的表格即可与此表格一起使用。


(图片1)
正如您可能无法从所附图片中看到的那样,我的总机有十个命令按钮和标签。 这些命令按钮和标签遵循特定的命名“cmdOption1”的约定(因为我知道你们遵循同样的原则!),“cmdOption2”等,以及“lblOption1”,“lblOption2”,等等。你可以忽略一些表格上的内容,但您可以看到它实际上只是对旧版MS Access标准总机的修改。 当我们深入研究时,就会发现:
表单本身具有tblSwitchboards的记录源。 窗体的“允许添加”和“允许删除”的属性均设置为“否”。当用户浏览菜单时,窗体将过滤所需的特定记录(仅显示一个记录和一个记录)。 为了使此表格与表格配合使用,我们必须执行几个步骤:
注意:我的某些代码未显示,因为与此无关。
Option Explicit
Option Compare Database 
Private Const intButtons = 10 
Private Sub Form_Open(Cancel As Integer)
On Error GoTo EH
    Me.Filter = "User = " & gintUserRights & _
    " AND ItemNumber = 0 AND Argument = 'Default'"
    Me.FilterOn = True
    Exit Sub
EH:
    MsgBox "There was an error initializing the Form!  " & _
        "Please contact your Database Administrator.", vbCritical, "Error!"
    Exit Sub
End Sub
我们建立常量intButtons来指示此Form使用多少个按钮。 很高兴知道我们可以根据需要随时扩展。
然后,当表单打开时,我们将按该用户的“默认”总机页面进行过滤。 很简单,到目前为止,对不对?
当我们选择另一个配电盘页面移动时,代码将根据所选页面标题(根据适当的用户)过滤表单,因此当该过滤器完成时,我们需要显示此页面的配电盘选项:
Private Sub Form_Current()
On Error GoTo EH
    FillOptions
    Exit Sub
EH:
    Exit Sub
    MsgBox "There was an error moving to the current Record!  " & _
        "Please contact your Database Administrator.", vbCritical, "Error!"
End Sub
必须放在窗体的OnCurrent事件中,否则初始页面将无法正确填充。
然后,相关的过程以填写表格的选项:
Private Sub FillOptions()
On Error GoTo EH
    Dim dbOptions As Database
    Dim rstOptions As Recordset
    Dim strSQL As String
    Dim intOption As Integer
    Me.cmdOption1.SetFocus
    For intOption = 2 To intButtons
        Me("cmdOption" & intOption).Visible = False
        Me("lblOption" & intOption).Visible = False
    Next intOption
    Set dbOptions = CurrentDb()
    strSQL = "SELECT * FROM tblSwitchboards" & _
        " WHERE User = " & gintUserRights & _
        " AND ItemNumber > 0 AND SwitchboardID = " & Me.SwitchboardID & _
        " ORDER BY ItemNumber;"
    Set rstOptions = dbOptions.OpenRecordset(strSQL, dbOpenDynaset)
    If rstOptions.EOF Then
        Me.lblOption1.Caption = "There are no items for this Switchboard page"
    Else
        While Not rstOptions.EOF
            Me("cmdOption" & rstOptions!ItemNumber).Visible = True
            Me("lblOption" & rstOptions!ItemNumber).Visible = True
            Me("lblOption" & rstOptions!ItemNumber).Caption = rstOptions!ItemText
            rstOptions.MoveNext
        Wend
    End If
    rstOptions.Close
    dbOptions.Close
    Set rstOptions = Nothing
    Set dbOptions = Nothing
    Exit Sub
EH:
    MsgBox "There was an error listing the Options on the Form!  " & _
        "Please contact your Database Administrator.", vbOKOnly, "WARNING!"
    Exit Sub
End Sub
您可能已经注意到,此代码起作用的关键子句位于此处:
" WHERE User = " & gintUserRights
仅显示适用于该特定用户的总机项目。
最后一件事。 我们如何确定单击菜单项时的操作?
首先,每个命令按钮和选项标签的OnClick EvenT中必须具有以下内容:
=SelectOption(x)
其中“ x”是命令按钮或选项标签的特定编号(1-10)。 这将执行以下功能:
Private Function SelectOption(intOption As Integer)
On Error GoTo EH
    RestoreForm Me.Form.Name
    Const optSwitchboard = 1
    Const optFormAdd = 2
    Const optFormBrowse = 3
    Const optOpenReport = 4
    Const optExit = 6
    Const ErrCancelled = 2501
    Dim dbOption As Database
    Dim rstOption As Recordset
    Dim strSQL As String
    Set dbOption = CurrentDb()
    strSQL = "SELECT * FROM tblSwitchboards" & _
        " WHERE User = " & gintUserRights & _
        " AND SwitchboardID = " & Me.SwitchboardID & _
        "  AND ItemNumber=" & intOption & ";"
    Set rstOption = dbOption.OpenRecordset(strSQL, dbOpenDynaset)
    If Not rstOption.EOF Then
        Select Case rstOption!Command
            Case optSwitchboard
                Me.Filter = "User = " & gintUserRights & _
                    " AND ItemNumber = 0" & _
                    " AND SwitchboardID = " & rstOption!Argument
                Me.FilterOn = True
            Case optFormAdd
                DoCmd.Close acForm, Me.Form.Name
                DoCmd.OpenForm rstOption!Argument, , , , acAdd
                GoTo SelectOption_Exit
            Case optFormBrowse
                DoCmd.Close acForm, Me.Form.Name
                DoCmd.OpenForm rstOption!Argument
                GoTo SelectOption_Exit
            Case optOpenReport
                DoCmd.OpenReport rstOption!Argument, acPreview
                GoTo SelectOption_Exit
            Case optExit
                DoCmd.Quit
            Case Else
                MsgBox "Unknown option."
        End Select
    Else
        MsgBox "There was an error reading the Switchboards Table."
        GoTo SelectOption_Exit
    End If
SelectOption_Exit:
On Error Resume Next
    rstOption.Close
    dbOption.Close
    Set rstOption = Nothing
    Set dbOption = Nothing
    Exit Function
EH:
    If (Err = ErrCancelled) Then
        Resume Next
    Else
        MsgBox "There was an error executing the command.  " & _
            "Please contact your Database Administrator", vbCritical
        Resume SelectOption_Exit
    End If
End Function
如果您正确设置了总机表,则永远不会遇到任何错误。 但是,为了以防万一,有处理有错误了(因为我知道你们包括错误所有的代码处理,对吧?)
就是这样! 它实际上并不太复杂,但是也许有些人可能认为它太艰巨而无法解决。 现在您有了一些选择。
我也希望对执行此代码的更好方法提供任何反馈。 我总是愿意学习!
希望这麻!
附加图片
文件类型:png Main Menu.png (65.6 KB,35239视图)

From: https://bytes.com/topic/access/insights/957166-how-create-user-permissions-customized-menus-ms-access

版权声明:本文为cxygs5788原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/cxygs5788/article/details/106351064