这是在较新版本的 Access 中删除用户级安全性的简单解决方案;使用大量的 VBA。
第 1 步:创建表格
首先,创建一个表。我会命名我LogininfoT
的。现在,对于表内的列,将它们命名为EmployeeID
、LoginID
、LoginPassword
、EmployeeName
,最后是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
尽管一旦对每个表单都这样做,安全性就会起作用,您需要登录到管理员帐户才能更改任何内容。如果您只是一个用户,您可以正常使用表单(单击按钮、编辑子表单上的数据等)但是您不能自行编辑表单。