如何使类变量在VBA中的模块之间持久存在

时间:2019-04-03 16:24:09

标签: vba class

我正在尝试寻找一种方法来使类变量在模块之间持久存在。 我有一个使用类,用于存储典型的用户数据:名称,域,管理员等。

我想在整个会话过程中(用户使用该工具时)存储这些信息,但是看来我无法做到这一点。下面是一个示例,感谢您的帮助/咨询! JP

这是课程模块:

Private cLoggedDomain As String
Private cLoggedRole As String
Private cDepartment As String
Private cEmployeeName As String
Private cManagerName As String
Private cEmp_ID As Long
Private cEmployeeInfo As Collection

Public Property Let SetUser(value As String)
    'RECIEVES THE LOGGED DOMAIN AS STRING
    'GETS THE DB ATTRIBUTES FROM SQL
    Set cEmployeeInfo = GetInfoFromSearch("Employee, manager, department, ety_type, emp_ID", _
                                         "domainID = '" & value & "'", _
                                         "Employee", "v_roster_empViewALL")

    cLoggedDomain = value
    cEmployeeName = cEmployeeInfo(1)(1)
    cManagerName = cEmployeeInfo(1)(2)
    cDepartment = cEmployeeInfo(1)(3)
    cLoggedRole = cEmployeeInfo(1)(4)
    cEmp_ID = cEmployeeInfo(1)(5)
End Property

Public Property Get LoggedDomain() As String
    LoggedDomain = cLoggedDomain
End Property

Public Property Let LoggedDomain(value As String)
    cLoggedDomain = value
End Property

Public Property Get LoggedRole() As String
    LoggedRole = cLoggedRole
End Property

Public Property Get LoggedDepartment() As String
    LoggedDepartment = cDepartment
End Property

Public Property Get LoggedEmployeeName() As String
    LoggedEmployeeName = cEmployeeName
End Property

Public Property Get LoggedManagerName() As String
    LoggedManagerName = cManagerName
End Property

Public Property Get LoggedEmpId() As String
    LoggedEmpId = cEmp_ID
End Property

以及使用它的模块,效果很好:

Public Sub New_LoadMain()
Dim s As Worksheet
Dim loggedUser As New cRoles

    'CHECK TO SEE IF USER IS LOGGED IN
    If loggedUser.LoggedDomain = "" Then
        'Set loggedUser = New cRoles
         loggedUser.SetUser = Environ("username")

    Else

    End If

    Call test

但是,当我尝试使用测试模块时,出现with块错误吗?

Sub test()
Dim test As cRoles
Dim t As String

t = test.LoggedDepartment

End Sub

1 个答案:

答案 0 :(得分:1)

类模块为对象定义了公共接口:它们是蓝图,在使用New关键字进行实例化之前,它们没有任何意义。

执行此操作时:

Dim test As cRoles

您为对象指针分配了内存,并告诉编译器该对象实现了cRoles接口;这样便可以输入test.并获取该界面上所有公共成员的列表。

但是该对象指针没有指向任何对象:Nothing(字面意思)。您需要创建该类的新实例才能访问对象test所指向的对象:

Set test = New cRoles

现在访问test成员将不再引发错误91。

现在,每个实例都封装了自己的状态:将工作簿中的每个工作表视为一个Worksheet实例:每个工作表都有自己单独的内容,但是所有工作表都可以通过相同的Worksheet进行操作界面,无论您使用的是Sheet1还是Sheet42

您的cRoles类的所有实例也是如此:

Dim test1 As cRoles
Set test1 = New cRoles
test1.SetUser = user1

Dim test2 As cRoles
Set test2 = New cRoles
test2.SetUser = user2

Debug.Print test1.LoggedEmpId, test2.LoggedEmpId

两个实例是完全不同的,并且每个实例都有自己的内部状态。如果那是您想要的,那么为了在一个地方创建实例并在另一个地方使用它,您需要将对象引用作为参数传递:

Public Sub Test()
    Dim thing As cRoles
    Set thing = New cRoles
    thing.SetUser = Environ("username")
    DoSomething thing
End Sub

Private Sub DoSomething(ByVal auth As cRoles)
    Debug.Print auth.LoggedEmpId
End Sub

注意:

  • 您通常希望传递参数ByVal
  • 避免使用As New,因为那样会产生一个自动实例化的对象,并且行为可能会或可能不会发生。
  • 您可以在标准模块中声明一个全局范围Public AuthInfo As cRoles变量,然后是一个负责创建对象和设置此全局范围引用的过程。然后,您可以在VBA项目中的任何地方访问AuthInfo-需要注意的是,现在可以通过VBA项目中的任何代码写入该全局变量。尽可能使用局部变量和参数。