财产使用无效。如何遍历属于对象的集合?

时间:2015-09-08 16:26:08

标签: excel vba excel-vba

我是Excel VBA的初学者,我正在尝试使用自定义类来组织一些数据。我已经看了很多例子,但是我很难找到我正在尝试做的很好的例子。

我的数据包含要对其执行的零件,数量和制造操作的列表。在我命名为" MOPart"的自定义类中,每个部分都有一个属性用于其名称和数量,但它为每个进程处理了一个属性集合。

在我的电子表格中,每个制造过程都有一个新行,因此该部件名称和数量将有一个重复的条目。我要做的是遍历每一行,检测是否已有一个与该部件名称匹配的对象;如果没有,则创建一个新的MOPart对象,但如果有,则将该行上的制造过程的名称添加到现有对象的集合属性中。

我想要作为对象属性的一个例子:

part.name = ABC123
part.qty = 12
part.routings(1) = Laser
part.routings(2) = Machining
part.routings(3) = Weld

以下是我到目前为止的代码。我的课程模块,MOPart:

Option Explicit

Private pQty As Integer
Private pRoutings As Collection
Private pname As String

Private Sub Class_Initialize()
    Set pRoutings = New Collection
End Sub

Property Get Name() As String
    Name = pname
End Property
Property Let Name(vname As String)
    pname = vname
End Property

Property Get qty() As Integer
    qty = pQty
End Property
Property Let qty(vqty As Integer)
    pQty = vqty
End Property

Property Set Routings(c As Collection)
    Set pRoutings = c
End Property

Property Get Routing(v As Integer) As String
    Routing = pRoutings(v)
End Property

我的模块测试了这个:

Option Explicit

Dim mps As Collection

Sub TestMod()
    Dim partexist As Boolean
    Dim i As Integer
    Dim rtg As String
    Dim mp As MOPart
    Dim crtg As Collection

Set mps = New Collection

' test first few entries in the data set
For i = 2 To 10
    partexist = False
    Set mp = New MOPart

    ' for each entry beisdes the first
    If mps.count > 0 Then

        ' loop through collection to find if there is an entry already
        For Each mp In mps

            ' if the part already exists
            If mp.Name = ActiveSheet.Cells(i, 1).Value Then
                partexist = True            'set flag that part exists
                crtg.Add ActiveSheet.Cells(i, 7).Value  ' add new routing
                Set mp.Routings = crtg
            End If
        Next mp
    End If

    ' if part name not found in list of parts
    If Not partexist Then

        ' Set properties for new part
        With mp
            .Name = ActiveSheet.Cells(i, 1).Value
            .qty = ActiveSheet.Cells(i, 4).Value
        End With

        Set crtg = New Collection  ' new collection representing routings for new part
        crtg.Add ActiveSheet.Cells(i, 7).Value
        Set mp.Routings = crtg

        ' add to collection of parts
        mps.Add mp

    End If

Next i



' after objects are all created, loop thru each routing of each part
For Each mp In mps
    For i = 1 To mp.Routings.count     ' COMPILER ERROR HERE: invalid use of property
' Also tried this line as for each rtg in mp.Routings
        MsgBox (mp.Name & "    " & mp.qty & "    " & mp.Routing(i))
    Next i
Next mp

End Sub

当我使用mp.Routings时,编译器似乎并不喜欢。我确信这是一些我忽略的简单语法错误,但我似乎无法弄明白。任何建议表示赞赏;也许有一种更清洁的方式来做我正在做的事情,我也愿意听到。

提前致谢。

编辑1:感谢Ron在下面的评论建议我添加一个"添加"自定义类的方法。我添加了一个add方法如下:

Public Sub add(rtg As String)
    pRoutings.add rtg
End Sub

我还添加了一个CountRoutings方法,它会返回一些路由:

Public Function CountRoutings() As Integer
    CountRoutings = pRoutings.count
End Function

在我的测试模块中,我将For i = 1 to mp.Routings.Count更改为For i = 1 to mp.CountRoutings

但是,我仍然不明白为什么我不能使用mp.Routings.count。我是否需要一个单独的类模块用于路由或什么?或者我需要一个"属性get"路线?

1 个答案:

答案 0 :(得分:0)

ClassModule:MOPart

Option Explicit

Private pQty As Long
Private pRoutings As Collection
Private pname As String

Private Sub Class_Initialize()
    Set pRoutings = New Collection
End Sub

Property Get Name() As String           '--------------------------------------
    Name = pname
End Property
Property Let Name(vname As String)
    pname = vname
End Property

Property Get Qty() As Long              '--------------------------------------
    Qty = pQty
End Property
Property Let Qty(vqty As Long)
    pQty = vqty
End Property

Property Set Routings(c As Collection)  '--------------------------------------
    Set pRoutings = c
End Property
Property Get Routings() As Collection
    Set Routings = pRoutings
End Property

Public Function getRouting(ByVal v As Long) As String
    getRouting = pRoutings(v)
End Function

测试模块:

Option Explicit

Dim mps As Collection

Public Sub test()
    setObjects
    testObjects
End Sub

Public Sub setObjects()
    Dim i As Long, j As Long, mp As MOPart, rtg As Collection
    Set mps = New Collection
    With ActiveSheet
        For i = 2 To 4
            Set mp = New MOPart
            mp.Name = .Cells(i, 1).Value2:  mp.Qty = .Cells(i, 4).Value2
            Set rtg = New Collection
            For j = 2 To 4
                rtg.Add .Cells(j, 7).Value2
            Next
            Set mp.Routings = rtg:  mps.Add mp
        Next
    End With
End Sub

Public Sub testObjects()
    Dim i As Long, mp As MOPart, msg As String
    For Each mp In mps
        With mp
            msg = msg & "part.name: " & vbTab & mp.Name & vbCrLf
            msg = msg & "part.qty: " & vbTab & vbTab & mp.Qty & vbCrLf
            For i = 1 To mp.Routings.Count
                msg = msg & "part.routings(" & i & "):" & vbTab & mp.getRouting(i) & vbCrLf
            Next: msg = msg & vbCrLf
        End With
    Next: MsgBox msg
End Sub

测试文件:

Test file

结果:

Result

发布的代码中的一些问题:

  • “设置路由()”和“获取路由()”(缺少“s”)
  • Get属性的参数必须少于Set
  • 由于初始化后If mps.count > 0
  • ,mps集合不会被填充