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

如何在VBA中使类变量在模块之间持久化,vba,class,Vba,Class,我试图找到一种方法,使类变量在模块之间持久化。 我有一个use类,它存储典型的用户数据:名称、域、经理等 我希望在会话的整个生命周期内(当用户使用该工具时)存储这些信息,但看起来我无法做到这一点。下面是一个例子,感谢您的帮助/建议! 太平绅士 以下是课堂模块: Private cLoggedDomain As String Private cLoggedRole As String Private cDepartment As String Private cEmployeeName As St

我试图找到一种方法,使类变量在模块之间持久化。 我有一个use类,它存储典型的用户数据:名称、域、经理等

我希望在会话的整个生命周期内(当用户使用该工具时)存储这些信息,但看起来我无法做到这一点。下面是一个例子,感谢您的帮助/建议! 太平绅士

以下是课堂模块:

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
然而,当我尝试使用测试模块时,我得到了一个带块错误的消息

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

t = test.LoggedDepartment

End Sub

类模块定义了对象的公共接口:它们是蓝图,在用
New
关键字实例化之前毫无意义

执行此操作时:

Dim test As cRoles
为对象指针分配内存,并告诉编译器该对象实现了
cRoles
接口;这就是如何键入
test.
并获取该界面上所有公共成员的列表

然而,该对象指针不指向任何对象:它是
(字面意思)。您需要创建该类的新实例,以便访问
test
指向的对象:

Set test = New cRoles
现在访问
test
成员将不再抛出错误91

现在,每个实例都封装了自己的状态:将工作簿中的每个工作表视为一个
工作表
实例:每个工作表都有自己独立的内容,但所有工作表都可以通过相同的
工作表
界面进行操作,而不管您是查看
工作表1
还是
工作表42

对于
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
  • 避免将
    作为新的
    ,因为这会生成一个自动实例化的对象,并且会产生预期的行为
  • 您可以在标准模块中声明一个全局范围
    Public AuthInfo As cRoles
    变量,然后是一个负责创建对象和设置此全局范围引用的过程。然后,您可以访问VBA项目中的任何地方的
    AuthInfo
    ——需要注意的是,该全局变量现在可以由VBA项目中的任何代码写入。如果可能,最好使用局部变量和参数

test
方法中,您没有将
test
(尽量不要使用与您的方法相同的名称…)设置到
cRoles
的实例-当您尝试访问它时,它仍然是
侧注,
SetUser
属性可能应该是一个方法(
Sub
)。只写属性是OOP中的一种设计风格。这是类的一个很好的概述,谢谢。设置全局变量实现了我想要的!再次感谢。