变量未在VBA脚本中定义

时间:2016-07-13 16:34:57

标签: vba object ms-access

我养成了在所有MS Access VBA脚本的顶部使用Option Explicit的好习惯。但是,对于此功能,它会显示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

我可能会错过具体的参考资料吗?

1 个答案:

答案 0 :(得分:5)

Option Explicit 强制声明所有变量

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

您使用returnthis关键字将本地变量String声明为Dim

Dim returnthis As String

这是您声明本地过程范围)变量的方式。

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

Option Explicit
Private foo As Object

范围变量如何取决于您使用它们的位置 - 如果变量仅在一个过程中使用过,那么最好将其范围扩展到该过程并将其声明为本地变量变量

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

Dim objSysInfo As Object
Dim objUser As Object

我知道我们不在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
    

完整代码可能如下所示:

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

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

Dim value As String
value = GetUserName(FirstName)