2

我有一个表,其中包含用户名、密码和 isadmin 的是/否列。

如果他们使用在“isadmin”下具有复选标记的帐户登录,我该如何做到这一点,他们可以访问设计视图、功能区等?虽然如果他们使用在 isadmin 框下没有复选标记的帐户登录,他们只能查看表单,不能编辑它们,并且功能区无法访问?

我只是不知道从哪里开始,因为我假设有一种方法可以将数据库保存为只有用户才能查看表单的单独副本,如果管理员运行他的副本,他会获得对表的所有更改(通过表格)用户制作的。因此,当管理员编辑表单并保存它时,它不会像保存时那样删除所有用户的数据,它也被保存到管理员的副本中。我真的很困惑。

我正在使用 Access 2013

4

1 回答 1

4

这是在较新版本的 Access 中删除用户级安全性的简单解决方案;使用大量的 VBA。

第 1 步:创建表格

首先,创建一个表。我会命名我LogininfoT的。现在,对于表内的列,将它们命名为EmployeeIDLoginIDLoginPasswordEmployeeName,最后是IsAdmin。将 EmployeeID 设为您的密钥,并将 IsAdmin 设为 YES/NO 字段。

为了测试,将两个用户添加到此表中。有了这些信息:

EmployeeID LoginID LoginPassword EmployeeName IsAdmin
1          1111    1234          Bob          [x]
2          2222    1234          Stewert      [ ]

第 2 步:创建表单

现在我们已经制作了表格,让我们设计表格来使用这组数据。

我将我的表单命名为 LoginF。进入设计视图,按下一个文本框、一个组合框和一个按钮。对于组合框,将文本重命名为“登录 ID”(您可以将其更改为适合您需要的任何内容),对于文本框,将文本输入为密码(再一次,将其更改为您想要的任何内容,它不会影响结果)。按钮中的文本可以是任何你想要的,我将把登录放在上面。

单击组合框并将其重命名。我将把它命名为 LoginCmBx。接下来,单击文本框并将其重命名,我将其命名为 PasswordTxt。最后,单击按钮并重命名,我将其命名为 LoginBtn。

再次单击组合框,然后在事件选项卡下,进入更新后脚本。使用代码并输入:

Private Sub LoginCmBx_AfterUpdate()

    Me.PasswordTxt.SetFocus

End Sub

这使得在您选择用户名后,它会自动将焦点放在密码文本框上,这样您就可以立即开始输入,而无需使用键盘上的 TAB 或使用鼠标。

接下来,转到按钮并在事件选项卡下,进入 On Click 脚本。使用代码并输入:

Private Sub LoginBtn_Click()

    If IsNull(Me.LoginCmBx) Or Me.LoginCmBx = "" Then
      MsgBox "You must enter a User Name.", vbOKOnly, "Required Data"
        Me.LoginCmBx.SetFocus
        Exit Sub
    End If

    If IsNull(Me.PasswordTxt) Or Me.PasswordTxt = "" Then
      MsgBox "You must enter a Password.", vbOKOnly, "Required Data"
        Me.PasswordTxt.SetFocus
        Exit Sub
    End If

    If Me.PasswordTxt.Value = DLookup("LoginPassword", "LoginInfoT", _
            "[EmployeeID]=" & Me.LoginCmBx.Value) Then

        EmployeeID = Me.LoginCmBx.Value

           On Error Resume Next
           DoCmd.DeleteObject acQuery, "IsAdminQ"
   On Error GoTo Err_LoginBtn_Click

   Dim qdef As DAO.QueryDef
   Set qdef = CurrentDb.CreateQueryDef("IsAdminQ", _
                                       "SELECT IsAdmin " & _
                                       "FROM LoginInfoT " & _
                                       "WHERE EmployeeID = " & LoginCmBx.Value)

Exit_LoginBtn_Click:
DoCmd.Close acForm, "LoginF", acSaveNo
        DoCmd.OpenForm "MenuF"
   Exit Sub
Err_LoginBtn_Click:
   MsgBox Err.Description
   Resume Exit_LoginBtn_Click

    Else
      MsgBox "Password Invalid. Please Try Again", vbOKOnly, _
            "Invalid Entry!"
        Me.PasswordTxt.SetFocus
    End If

End Sub

它的作用是检查您是否选择了用户名,如果没有,它会吐出一个错误,告诉用户选择一个。如果你这样做了,它会检查你是否输入了密码。如果他们没有,它会吐出另一个错误,说他们没有输入密码。如果他们同时选择了这两个,并且密码与表中您选择的用户名的密码不匹配,则会吐出一个错误,提示您密码错误。如果您选择的用户名的密码正确,它会登录。然后它将关闭您当前所在的表单,并打开一个名为“MenuF”的新表单,它还将创建一个包含少量信息的查询在您选择的用户名下,无论是否是管理员。我们还没有创建 MenuF,所以让我们快速创建。不过,我们还没有完成 LoginF,

创建表单,然后按下按钮。这是您的菜单表单,您可以创建任意数量的按钮到其他表单,或者甚至只是在这里放一个子表单并拥有整个数据库。按下按钮,您可以将文本命名为任何您想要的名称。我把我的作为注销。将按钮命名为 MenuLogOutBtn。进入事件选项卡,在 On Click 脚本下单击代码并输入:

Private Sub MenuLogOutBtn_Click()
   DoCmd.DeleteObject acQuery, "IsAdminQ"
           DoCmd.OpenForm "LoginF"
           DoCmd.Close acForm, "MenuF", acSaveNo
End Sub

这样做是删除登录按钮创建的查询,再次打开登录表单,然后关闭菜单。简单的!

现在我需要你扔下一个复选框,并将其命名为 MyCheckbox。此框不需要特殊编码或控制源。虽然我确实建议将可见更改为否,并删除随之而来的文本。

现在,转到表单的事件属性并在打开脚本下转到代码并输入:

Private Sub Form_Open(Cancel As Integer)

  Me.MyCheckbox.Value = GetLoginStateIsAdmin()

  If GetLoginStateIsAdmin = True Then
Me.ShortcutMenu = True
DoCmd.ShowToolbar "Ribbon", acToolbarYes
DoCmd.ShowToolbar "Menu Bar", acToolbarYes
Application.SetOption "ShowWindowsinTaskbar", True
DoCmd.SelectObject acTable, , True
  Else
Me.ShortcutMenu = False
DoCmd.ShowToolbar "Ribbon", acToolbarNo
DoCmd.ShowToolbar "Menu Bar", acToolbarNo
Application.SetOption "ShowWindowsinTaskbar", False
DoCmd.NavigateTo "acNavigationCategoryObjectType"
DoCmd.RunCommand acCmdWindowHide
  End If

End Sub

它所做的是附加到查询IsAdmin列并提供GetLoginStateIsAdmin该布尔变量的复选框信息。之后,它会启动一个简单的 If 语句,如果您不是管理员,它会关闭菜单栏并禁用右键单击;如果是,它允许您进行右键单击,并且所有菜单栏都可见。

虽然如果您还没有注意到,我们的复选框还没有从查询中获取信息!不好了!

第 3 步:创建公共模块

如果您小心翼翼,您会注意到此时连登录代码都不起作用。首先,我们需要一些公共模块。转到功能区中的“创建”选项卡,然后创建一个模块。输入:

    Public EmployeeID As Long

Save this module as LoginModule.

Create another module, and type this in:

    Function GetLoginStateIsAdmin()
    '
      Dim rst As DAO.Recordset

      Set rst = CurrentDb.OpenRecordset("IsAdminQ")
      GetLoginStateIsAdmin = Nz(rst(0), False)

      Set rst = Nothing
    '
    End Function

Save this one as GetAdmin.

Lets create one more module; so the user opening the database can't by bass stuff by using the shift key to launch it.

Type this in it:

Function ap_DisableShift()
'This function disable the shift at startup. This action causes
'the Autoexec macro and Startup properties to always be executed.

On Error GoTo errDisableShift

Dim db As DAO.Database
Dim prop As DAO.Property
Const conPropNotFound = 3270

Set db = CurrentDb()

'This next line disables the shift key on startup.
db.Properties("AllowByPassKey") = False

'The function is successful.
Exit Function

errDisableShift:
'The first part of this error routine creates the "AllowByPassKey
'property if it does not exist.
If Err = conPropNotFound Then
Set prop = db.CreateProperty("AllowByPassKey", _
dbBoolean, False)
db.Properties.Append prop
Resume Next
Else
MsgBox "Function 'ap_DisableShift' did not complete successfully."
Exit Function
End If

End Function

将其保存为 ShiftModule。

我们完成了模块!现在让我们回到 LoginF。

第 4 步:完成 LoginF

转到表单的事件选项卡,然后单击加载脚本。点击代码,然后输入:

Private Sub Form_Load()
   On Error Resume Next
   DoCmd.DeleteObject acQuery, "CustomerMoreInfoQ"
End Sub

这样做是为了确保在此表单启动时删除登录按钮创建的查询,以防用户在未注销的情况下关闭数据库。因此,如果您单击登录,它不会导致错误,因为查询仍然不存在。

第 5 步:测试它。

在表单视图中运行表单 LoginF,并选择 Bob 作为用户名。在密码文本框中输入密码 1234,然后单击登录。它应该打开 MenuF,您会看到所有菜单,您可以右键单击。好的。现在,注销并使用 Stewert 登录,使用相同的密码。现在您看到所有菜单都自行删除了,而且您无法右键单击!耶!

为了额外的安全性,在 LoginF 的其他选项卡中,确保快捷菜单设置为否。这会将右键单击设置为始终禁用;因为此时您还没有以用户身份登录。它不知道您是否是管理员。

第 6 步:在启动时禁用工具栏并在启动时启动 LoginF。

转到文件 > 选项 > 当前数据库。

在显示表单下,选择 FormF。在导航部分下,取消单击显示导航窗格。

点击ok,然后回到LoginF;进入 On Load 代码并将其添加到 End Sub 之前:

DoCmd.ShowToolbar "Ribbon", acToolbarNo

你完成了!保存您的数据库,然后关闭它并再次打开它。它应该加载无法右键单击的 LoginF 表单,没有菜单等。让菜单编辑内容的唯一方法是登录管理员帐户!

第 7 步:扩展

但是,这不会自动扩展您添加的表单越多。您需要将名为 MyCheckbox 的复选框(我建议复制+粘贴)添加到您添加的每个表单中,并将此代码添加到您添加的每个表单中:

Private Sub Form_Open(Cancel As Integer)

  Me.MyCheckbox.Value = GetLoginStateIsAdmin()

  If GetLoginStateIsAdmin = True Then
Me.ShortcutMenu = True
  Else
Me.ShortcutMenu = False
  End If

End Sub

尽管一旦对每个表单都这样做,安全性就会起作用,您需要登录到管理员帐户才能更改任何内容。如果您只是一个用户,您可以正常使用表单(单击按钮、编辑子表单上的数据等)但是您不能自行编辑表单。

于 2013-11-06T15:40:18.510 回答