【问题标题】:Excel VBA: Is there a way to reference an instance of a class stored in a dictionary?Excel VBA:有没有办法引用存储在字典中的类的实例?
【发布时间】:2017-06-13 07:54:12
【问题描述】:

我目前有使用下图所示数据结构存储的类实例。每个-List 项是一个字典,每个-Info 项是一个类的实例。

我在别处读到,如果您 Set 一个实例变量等于另一个实例,它只会引用原始实例。这是正确的吗?

我已经能够使用以下代码为fileInfo(1)(在图像中)创建一个引用。

Dim prflInfo As File_Info
Set prflInfo = New File_Info
Set prflInfo = fileList.Items(0)

我尝试使用以下代码引用 branchInfo 实例,但在尝试这样做时我得到了 Run-time error 13: Type mismatch

Dim prbrInfo As Branch_Info
With prflInfo
    Set prbrInfo = New Branch_Info
    brKey = .getbrKey(0)
    Set prbrInfo = .getbrItem(brKey)
End With

编辑:下面包含 File_Info 类的代码。所有其他类都遵循这个基本模型。

'Class Module: File_Info

'Initialise class variables
Private pfileID As Integer
Private pfilePath As String
Private pfileName As String

Private pbranchList As Scripting.Dictionary

'Declare variantcopy subroutine
Private Declare Sub VariantCopy Lib "OleAut32" (pvarDest As Any, pvargSrc As Any)

Private Sub Class_Initialize()
    Set pbranchList = New Scripting.Dictionary
End Sub

Public Property Let fileID(pfileIDi As Variant)
    pfileID = pfileIDi
End Property
Public Property Get fileID() As Variant
    fileID = pfileID
End Property

Public Property Let filePath(pfilePathi As Variant)
    pfilePath = pfilePathi
End Property
Public Property Get filePath() As Variant
    filePath = pfilePath
End Property

Public Property Let fileName(pfileNamei As Variant)
    pfileName = pfileNamei
End Property
Public Property Get fileName() As Variant
    fileName = pfileName
End Property

Public Sub addbrConn(branch As Branch_Info)
    pbranchList.Add branch.branchID, branch.brConn
    Debug.Print "addbrConn ID: " & branch.branchID
End Sub

Public Sub addBranch(branch As Branch_Info)
    pbranchList.Add branch.branchID, branch
    Debug.Print pbranchList.Count
End Sub

Public Function countbrList()
    countbrList = pbranchList.Count
End Function

Public Function getbrKey(Key As Variant)
    getbrKey = pbranchList.Keys(Key)
End Function

Public Function getbrItem(Key As Variant)
    getbrItem = GetByRefVariant(pbranchList.Items(Key))
End Function

Public Sub dpbrList()
    With pbranchList
        Debug.Print pbranchList.Count
        For k = 1 To pbranchList.Count
            Debug.Print .Keys(k - 1), .Items(k - 1)
        Next k
    End With
End Sub

Public Sub updbrList(branch As Branch_Info)
    Dim branchID As String
    branchID = branch.branchID

    If pbranchList.exists(branchID) Then
        pbranchList.Remove (branchID)
        pbranchList.Add branchID, branch
        Debug.Print "Complete: " & branchID & " added."
    Else
        Debug.Print "Error: " & branchID & "does not exist."
    End If
End Sub

Private Function GetByRefVariant(ByRef var As Variant) As Variant
    VariantCopy GetByRefVariant, var
End Function

有没有办法引用 branchInfo 类,以便更轻松地提取其中的数据?

谢谢!

伊什瓦

【问题讨论】:

  • 有,但是没有关于类属性和方法的代码,我很难回答你的问题。
  • 嗨 Ron,感谢您更新问题以包含内联图像。我添加了 File_Info 类信息。希望对您有所帮助!

标签: excel vba class dictionary instance


【解决方案1】:

我的做法有所不同,因为我使用For ... each 循环而不是引用项目编号来遍历键列表。这是一个使用两个级别的 sn-p。

您可以忽略将属性值写入数组的行,但它们是原始代码的一部分。

cf.DependentscDependentscFamily 对象中的字典

'Declarations in Main Module

Dim dF As Dictionary, cF As cFamily, cD As cDependents
Dim I As Long, J As Long
Dim V As Variant, W As Variant

...

For Each V In dF
    I = I + 1
    Set cF = dF(V)
    With cF
        vRes(I, 1) = .FirstName
        vRes(I, 2) = .LastName
        vRes(I, 3) = .Birthdate

        J = 2
        For Each W In .Dependents
            J = J + 2
            Set cD = .Dependents(W)
            With cD
                vRes(I, J) = .Relation
                vRes(I, J + 1) = .DepName
            End With
        Next W
    End With
Next V

请注意,按照您在问题中显示的顺序:

set Obj = new Obj
set Obj = myClass(0)

第一行是不必要的。

【讨论】:

    【解决方案2】:

    IMO 可以使用简单的VBA.Collection,这里以FileListBranchList 为例。在此示例中,List 类具有 ItemsInfo 类具有对 List 的引用,其中 ListVBA.Collection 的包装器。高温

    如需更多阅读,请查看例如here.

    文件列表类

    Option Explicit
    
    Private m_fileInfoCollection As FileInfoCollection
    
    Private Sub Class_Initialize()
        Set m_fileInfoCollection = New FileInfoCollection
    End Sub
    
    Public Property Get Items() As FileInfoCollection
        Set Items = m_fileInfoCollection
    End Property
    

    文件信息类

    Option Explicit
    
    Private m_branchList As BranchList
    
    Private m_fileID As Integer
    
    Private Sub Class_Initialize()
        Set m_branchList = New BranchList
    End Sub
    
    Public Property Get FileID() As Integer
        FileID = m_fileID
    End Property
    
    Public Property Let FileID(ByVal vNewValue As Integer)
        m_fileID = vNewValue
    End Property
    
    Public Property Get BranchList() As BranchList
        Set BranchList = m_branchList
    End Property
    

    FileInfoCollection 类

    Option Explicit
    
    Private m_collection As VBA.Collection
    
    Private Sub Class_Initialize()
        Set m_collection = New VBA.Collection
    End Sub
    
    Public Sub Add(ByVal newItem As FileInfo)
        m_collection.Add newItem, CStr(newItem.FileID)
    End Sub
    
    Public Function ItemByKey(ByVal key As String) As FileInfo
        Set ItemByKey = m_collection(key)
    End Function
    
    Public Function ItemByIndex(ByVal index As Long) As FileInfo
        Set ItemByIndex = m_collection(index)
    End Function
    
    Public Function Count() As Long
        Count = m_collection.Count
    End Function
    

    BranchList 类

    Option Explicit
    
    Private m_branchInfoCollection As BranchInfoCollection
    
    Private Sub Class_Initialize()
        Set m_branchInfoCollection = New BranchInfoCollection
    End Sub
    
    Public Property Get Items() As BranchInfoCollection
        Set Items = m_branchInfoCollection
    End Property
    

    BranchInfo 类

    Option Explicit
    
    Private m_branchID As Integer
    
    Public Property Get branchID() As Integer
        branchID = m_branchID
    End Property
    
    Public Property Let branchID(ByVal vNewValue As Integer)
        m_branchID = vNewValue
    End Property
    

    BranchInfoCollection 类

    Option Explicit
    
    Private m_collection As VBA.Collection
    
    Private Sub Class_Initialize()
        Set m_collection = New VBA.Collection
    End Sub
    
    Public Sub Add(ByVal newItem As BranchInfo)
        m_collection.Add newItem, CStr(newItem.branchID)
    End Sub
    
    Public Function ItemByKey(ByVal key As String) As BranchInfo
        Set ItemByKey = m_collection(key)
    End Function
    
    Public Function ItemByIndex(ByVal index As Long) As BranchInfo
        Set ItemByIndex = m_collection(index)
    End Function
    
    Public Function Count() As Long
        Count = m_collection.Count
    End Function
    

    标准模块

    Option Explicit
    
    Sub Demo()
        ' Fill
        Dim bi As BranchInfo
        Set bi = New BranchInfo
        bi.branchID = 111
    
        Dim fi As FileInfo
        Set fi = New FileInfo
        fi.FileID = 222
        fi.BranchList.Items.Add bi
    
        Dim fl As FileList
        Set fl = New FileList
        fl.Items.Add fi
    
        ' Get
        Dim fi1 As FileInfo
        Set fi1 = fl.Items.ItemByIndex(1)
    
        Dim bi1 As BranchInfo
        Set bi1 = fi1.BranchList.Items(1)
    End Sub
    

    【讨论】:

      猜你喜欢
      • 2021-06-19
      • 1970-01-01
      • 2013-02-24
      • 2018-11-26
      • 2020-05-08
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多