在这种情况下,DLookup如何工作?

问题描述:

新用户:)在这种情况下,DLookup如何工作?

我在下面的代码中得到了关于DLookup的问题。该代码假设只允许选定的用户打开表单。用户在tbl中并且On Error Resume Next代码正在工作,允许用户访问应用程序,但是当我注释掉On Error时,我得到运行时错误'13':类型不匹配。我希望有人能解释为什么On Error会失败并将其注释掉。我知道If语句需要条件来评估,那么如何获取用户名允许应用程序打开表单?

Private Sub Form_Open(Cancel As Integer) 

On Error Resume Next 

If DLookup("[CitrixID]", "tbl_UserAccess", "[CitrixID] = " & "'" & Environ("username") & "'") Then 

Else 

MsgBox "You do not have permission to access the application" 

DoCmd.Close 

End If 

End Sub 

这真的不是这样做的方式,但我会解释它做了什么。

DLookUp从表中查找值。在你的情况下,它从表CitrixID查找CitrixID,其中CitrixID等于用户名。然后它返回该用户名作为If声明的条件。

If声明,但预计该条件是要么TrueFalseNull,或数值(0 = falsy,所有其他符号truthy),其计算为假,而不是Windows用户名,这就是为什么发生错误。

如果你使用On Error Resume Next,如果DLookup返回一个字符串,你实际上跳到If语句中,因为这是下一件事。但是,如果它返回Null,因为它找不到该用户名,不会触发错误,因为Null是转换为false的有效值。

一些示例代码,以帮助您了解这一点:

Public Sub TestIfResumeNext() 
    If Null Then 
     Debug.Print Null 
    End If 
On Error Resume Next 
    If "A" Then 
     Debug.Print "A" 
    End If 
    If 1 Then 
     Debug.Print 1 
    End If 
    If 0 Then 
     Debug.Print 0 
    End If 
    If -1 Then 
     Debug.Print -1 
    End If 
End Sub 

这将返回"A"因为错误捕获,1-1因为他们truthy的,但不是Null,因为这是一个有效的falsy值,而不是0出于同样的原因。

如果您不想依赖此错误陷印行为,但希望保留其余逻辑,则可以简单地将DLookUp替换为DCount。由于0是虚假的,你甚至不需要检查它是否为0(但这样做是一个很好的做法imho)。

If DCount("[CitrixID]", "tbl_UserAccess", "[CitrixID] = " & "'" & Environ("username") & "'") Then 

或者,与比较

If DCount("[CitrixID]", "tbl_UserAccess", "[CitrixID] = " & "'" & Environ("username") & "'") <> 0 Then 

请注意,您现在可以缩短其使用If NotIf DCount = 0并删除Else

+0

谢谢你这么清楚解释! :) –

使用DLookup返回 “未发现”,因此所有你需要检查的是:

Private Sub Form_Open(Cancel As Integer) 

    If IsNull(DLookup("[CitrixID]", "tbl_UserAccess", "[CitrixID] = '" & Environ("username") & "'")) Then 
     MsgBox "You do not have permission to access the application." 
     DoCmd.Close 
    End If 

End Sub