You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.15 03:37:35