如何枚举VBA类模块中的多个集合

如何枚举VBA类模块中的多个集合,vba,Vba,在我的类模块中,我想列举两个不同的集合。然而,它似乎不起作用。我可以为其中一个集合使用数组,但这会使我在其他地方使用该类时更难编写代码 这可能吗?如果是,我有什么错 我试着在谷歌上搜索,但似乎找不到这方面的很多信息 clsPart: VERSION 1.0 CLASS BEGIN MultiUse = -1 'True END Attribute VB_Name = "clsPart" Attribute VB_GlobalNameSpace = False Attribute VB_Cr

在我的类模块中,我想列举两个不同的集合。然而,它似乎不起作用。我可以为其中一个集合使用数组,但这会使我在其他地方使用该类时更难编写代码

这可能吗?如果是,我有什么错

我试着在谷歌上搜索,但似乎找不到这方面的很多信息

clsPart:

VERSION 1.0 CLASS
BEGIN
  MultiUse = -1  'True
END
Attribute VB_Name = "clsPart"
Attribute VB_GlobalNameSpace = False
Attribute VB_Creatable = False
Attribute VB_PredeclaredId = False
Attribute VB_Exposed = False
Option Explicit

Private iPart As String
Private Type tSeqs
    SequenceNumbers As Collection
    RouterSequences As Collection
End Type
Private cc1 As tSeqs

Public Property Get SeqNumbers() As IUnknown
Attribute SeqNumbers.VB_UserMemId = -4
Attribute SeqNumbers.VB_MemberFlags = "40"
    Set SeqNumbers = cc1.SequenceNumbers.[_SeqNumbers]
End Property

Public Property Get RouterSeqs() As IUnknown
Attribute RouterSeqs.VB_UserMemId = -4
Attribute RouterSeqs.VB_MemberFlags = "40"
    Set RouterSeqs = cc1.RouterSequences.[_RouterSeqs]
End Property

Private Sub Class_Initialize()
    With cc1
        Set .SequenceNumbers = New Collection
        Set .RouterSequences = New Collection
    End With
End Sub

Private Sub Class_Terminate()
    With cc1
        Set .SequenceNumbers = Nothing
        Set .RouterSequences = Nothing
    End With
End Sub

Public Property Get PartNumber() As String
    PartNumber = iPart
End Property

Public Property Let PartNumber(lPart As String)
    iPart = lPart
End Property

Public Sub AddSequence(ByVal aSeq As String, ByVal aQty As Double)
    Dim iSeq As clsSeq
        If SeqExists(aSeq) Then
            Set iSeq = cc1.SequenceNumbers.Item(aSeq)
            iSeq.Qty = iSeq.Qty + aQty
        Else
            Set iSeq = New clsSeq
            With iSeq
                .Qty = aQty
                .Sequence = aSeq
            End With
            With cc1
                .SequenceNumbers.Add iSeq, iSeq.Sequence
                .RouterSequences.Add iSeq.Sequence
                SortSeqColl .RouterSequences
            End With
        End If
        Set iSeq = Nothing
End Sub

Public Function SequenceExists(ByVal Index As String)
    SequenceExists = SeqExists(Index)
End Function

Public Function Sequence(ByVal Index As String) As clsSeq
    Set Sequence = cc1.SequenceNumbers.Item(Index)
End Function

Private Function SeqExists(iSeq As String) As Boolean
    Dim V As Variant
        On Error Resume Next
        V = IsObject(cc1.SequenceNumbers.Item(iSeq))
        SeqExists = Not IsEmpty(V)
End Function

Private Sub SortSeqColl(ByRef sColl As Collection)
    Dim vItm As Variant
    Dim i As Long, j As Long
    Dim vTemp As Variant
        For i = 1 To sColl.Count - 1
            For j = i + 1 To sColl.Count
                If sColl(i) > sColl(j) Then
                    vTemp = sColl(j)
                    sColl.Remove j
                    sColl.Add vTemp, vTemp, i
                End If
            Next j
        Next i
End Sub

第一个集合是关于特定零件的特定信息(当前处于每个制造阶段的数量)。第二个集合只是零件可能处于的所有可能序列号(制造阶段)的列表,这随每个不同的零件而变化。当参考制造过程中的实际数量和位置数据时,我需要能够按照制造过程的相反顺序进行检查,以从最完整的第一个提取qty

您的收集类既是
SequenceCollection
又是
RouterCollection

这是行不通的:

或者这个:

打开对象浏览器(按F2键);右键单击某个位置并选择“显示隐藏成员”,然后找到
VBA.Collection
类-您将看到以下内容:

隐藏的
\u NewEnum
成员是产生
IUnknown
枚举数的对象,该枚举数是
为每个
使用的。这不是虚构的会员名称

更改您的
RouterSeqs
属性以返回它:

Set RouterSeqs = cc1.RouterSequences.[_NewEnum]
与编号相同:

Set SeqNumbers = cc1.SequenceNumbers.[_NewEnum]
需要方括号,因为就VBA而言,
前缀使
\u NewEnum
成为无效标识符;方括号使其解析为“外来标识符”,这是受支持的

现在,让我们想象一些虚构的客户端代码:

Public Sub EnumerateParts(ByVal parts As clsPart)
    Dim part As Object
    For Each part In parts
        '...
    Next
End Sub
如果
clsPart
类(protip:collection类应该有一个复数名称)有两个属性可以为每个
枚举启用
,那么VBA应该如何猜测使用哪个属性

不可能

选择一个作为集合类的枚举器,并将其命名为
NewEnum
,以遵守约定-放弃另一个

请注意,VBA将不接受此标志:


因为成员不能隐藏在VBA用户代码中(但在VB6中应该可以正常工作)。

我在让类枚举1个集合方面没有问题,但对于我正在寻找的功能,我想枚举2个。如果我正确理解了您的答案,这是不可能做到的,我需要为我的第二个收藏找到另一个解决方案,也许是一个数组。(我还用更多信息更新了我的问题)@GlennG公开自定义迭代器的原因无非是为每个
迭代启用客户端
。决定要为每个
枚举的内容,并使返回的成员为其生成枚举数-只能有一个。任何其他功能都与枚举机制无关。@GlennG在原始代码中,您在同一个类中指定了两次
属性RouterSeqs.VB\u UserMemId=-4
。这是非法的,因为所有成员只能分配唯一的ID。相反,创建两个集合类,然后从
clsPart
类中使用它们。
Set SeqNumbers = cc1.SequenceNumbers.[_NewEnum]
Public Sub EnumerateParts(ByVal parts As clsPart)
    Dim part As Object
    For Each part In parts
        '...
    Next
End Sub
Attribute SeqNumbers.VB_MemberFlags = "40"