这是在较新版本的 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 步:完成登录F
转到表单的事件选项卡,然后单击加载脚本。点击代码,然后输入:
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
尽管对每个表单都执行了此操作,但安全性仍然有效,您需要登录管理员帐户才能更改任何内容。如果你只是一个用户,你可以正常使用表单(点击按钮,编辑子表单上的数据等)你不能编辑它自己的表单。