变量未在VBA脚本中定义

wha*_*hat 0 ms-access vba object

我养成了Option Explicit在所有MS Access VBA脚本顶部使用的好习惯.但是,对于这个函数,它给出了一个Variable not defined错误,突出显示以该行开头的行Set objSysInfo =

Public Function GetUser(Optional whatpart = "username")

    Dim returnthis As String
    If whatpart = "username" Then GetUser = Environ("USERNAME"): Exit Function
    Set objSysInfo = CreateObject("ADSystemInfo")
    Set objUser = GetObject("LDAP://" & objSysInfo.UserName)
    Select Case whatpart
        Case "fullname": returnthis = objUser.FullName
        Case "firstname", "givenname": returnthis = objUser.givenName
        Case "lastname": returnthis = objUser.LastName
        Case Else: returnthis = Environ("USERNAME")
    End Select
    GetUser = returnthis

End Function
Run Code Online (Sandbox Code Playgroud)

我可能会错过一个具体的参考?

Mat*_*don 5

Option Explicit 强制声明所有变量.

这意味着您必须声明您正在使用的所有变量,否则您的代码将无法编译 - 正如您所注意到的那样.

您使用关键字将局部变量声明returnthis为a :StringDim

Dim returnthis As String
Run Code Online (Sandbox Code Playgroud)

这就是你声明一个本地(过程范围)变量的方式.

您可以使用关键字在模块范围声明变量Private(也Dim适用,但最好保留Dim本地)

Option Explicit
Private foo As Object
Run Code Online (Sandbox Code Playgroud)

你如何范围变量,取决于你使用它们,其中-如果一个变量在一个单独的程序只使用过的,那么它的更好的范围是该程序,并宣布它作为一个局部变量.

在这种情况下,你有objSysInfoobjUser未在任何地方声明.

Dim objSysInfo As Object
Dim objUser As Object
Run Code Online (Sandbox Code Playgroud)

我知道我们不参与Code Review,但是当我们在这里时,您的代码还存在其他问题:

  • 函数的返回类型是隐式的Variant.附加As String到函数签名的末尾.
  • 可选参数whatpart也是隐Variant式传递的ByRef,但是你只需要读取它,而不是写入并返回给调用者 - 所以声明它Optional ByVal whatpart As String = "username".
  • 首选Environ$函数Environ- 两者都做同样的事情,但Environ返回一个Variant,你隐式转换为String- 最佳使用Environ$并从一开始就使用字符串.
  • 而不是依赖于魔术,硬编码的字符串,使用Enum值和Select Case可能的合法值:

    Public Enum NamePart
        EnvironmentDefined
        FullName
        FirstName
        LastName
    End Enum
    
    Run Code Online (Sandbox Code Playgroud)

完整代码可能如下所示:

Public Enum NamePart
    EnvironmentDefined
    FullName
    FirstName
    LastName
End Enum

Public Function GetUserName(Optional ByVal part As NamePart = EnvironmentDefined) As String

    Dim result As String
    Dim sysInfo As Object
    Dim userInfo As Object

    If Namepart = EnvironmentDefined Then 
        GetUser = Environ$("USERNAME")
        Exit Function
    End If

    Set sysInfo = CreateObject("ADSystemInfo")
    Set userInfo = GetObject("LDAP://" & sysInfo.UserName)
    Select Case part
        Case FullName
            result = userInfo.FullName
        Case FirstName
            result = userInfo.GivenName
        Case LastName
            result = userInfo.LastName
        Case Else
            result = Environ$("USERNAME")
    End Select

    GetUserName = result

End Function
Run Code Online (Sandbox Code Playgroud)

注意,我没有包含GivenName枚举成员,因为它是多余的; 调用代码可以这样做:

Dim value As String
value = GetUserName(FirstName)
Run Code Online (Sandbox Code Playgroud)

  • @whatwhatwhat见编辑.祝好运! (2认同)