MS Access 2016:使用TempVars校验窗体权限时合法用户无法访问
排查权限验证失败的核心问题
从你的代码和描述来看,有几个致命的语法/逻辑错误直接导致了有权限用户无法访问窗体,我帮你逐一拆解:
1. 窗体Form_Load事件重复定义 + DLookup条件语法错误
你提供的代码里出现了两个Private Sub Form_Load()过程,这在VBA中是不允许的——会触发编译错误,导致窗体的加载逻辑要么完全不执行,要么只执行最后定义的那个。
更关键的是,第二个Form_Load里的DLookup条件存在语法漏洞:
' 原错误代码 Nz(DLookup("HasAccess", "tbl9EmployeeAccess", "EmployeeType_ID=" & TempVars("EmployeeType") & " FormName='" & Me.Name & "'"), False)
两个查询条件EmployeeType_ID=...和FormName='...'之间缺少AND连接符,导致DLookup无法正确解析条件,会返回Null,经过Nz处理后直接变成False,所以无论用户权限如何,都会触发拒绝访问的提示。
修正后的合并版Form_Load代码:
Private Sub Form_Load() ' 先完成窗体初始化 Me.txtUserName = Null Me.txtPassword = Null Me.txtUserName.SetFocus ' 修正权限验证的DLookup条件 If Nz(DLookup("HasAccess", "tbl9EmployeeAccess", "EmployeeType_ID=" & TempVars("EmployeeType") & " AND FormName='" & Me.Name & "'"), False) = False Then MsgBox "You do not have access to this location." DoCmd.Close acForm, Me.Name End If End Sub
2. 登录模块的逻辑顺序错误
你把空值检查放在了用户名和密码验证之后,这会导致如果用户输入空值,会先执行无效的用户名/密码验证逻辑,甚至可能触发意外错误。应该把空值检查放在最前面:
修正后的登录按钮逻辑顺序:
Private Sub btnLogin_Click() Dim rs As Recordset ' 第一步:先检查必填项是否为空 If IsNull(Me.txtUserName) Or IsNull(Me.txtPassword) Then MsgBox "You must enter both login ID and password.", vbOKOnly + vbInformation, "Required Data" Me.txtUserName.SetFocus Exit Sub End If ' 第二步:验证用户名是否存在 Set rs = CurrentDb.OpenRecordset("Employees", dbOpenSnapshot, dbReadOnly) rs.FindFirst "UserName='" & Me.txtUserName & "'" If rs.NoMatch = True Then Me.lblWrongUser.Visible = True Me.txtUserName.SetFocus Exit Sub End If Me.lblWrongUser.Visible = False ' 第三步:验证密码是否正确 If rs!Password <> Me.txtPassword Then Me.lblWrongPass.Visible = True Me.txtPassword.SetFocus Exit Sub End If Me.lblWrongPass.Visible = False ' 后续的权限判断和TempVars设置... End Sub
3. 权限字段的一致性问题
登录代码里,你判断管理员权限用的是rs!EmployeeType >=4,但存入TempVars的是rs!EmployeeType_ID.Value——这两个字段的含义是否一致?比如:
EmployeeType是权限名称(文本类型,如"Admin")EmployeeType_ID是权限的数字ID(数值类型,如4对应管理员)
如果是这种情况,那判断管理员的条件应该改成rs!EmployeeType_ID >=4,否则文本字段和数字的比较会导致逻辑错误。
额外调试建议
如果修正以上问题后仍无法访问,可以做以下验证:
- 在窗体
Form_Load的权限验证代码前,添加MsgBox TempVars("EmployeeType").Value,确认TempVars是否正确存储了用户的权限ID - 手动在Access查询中执行以下SQL,确认是否存在对应权限的记录:
SELECT HasAccess FROM tbl9EmployeeAccess WHERE EmployeeType_ID=你的测试权限ID AND FormName='frmMain' - 检查
tbl9EmployeeAccess中的FormName字段值是否和窗体的实际名称完全一致(Access默认不区分大小写,但建议完全匹配)
内容的提问来源于stack exchange,提问作者Bobby
相关产品推荐
相关产品推荐

