2015-09-08 2 views
1

Я полный новичок в 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: Спасибо за комментарий Рона ниже, советуя добавить метод «добавить» в пользовательский класс. Я добавил метод добавления следующим образом:

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 на Для i = 1 to mp.CountRoutings

Однако, я до сих пор не понимаю, почему я не могу использовать mp.Routings.count. Нужен ли мне отдельный модуль класса для маршрутизации или что-то еще? Или мне нужен «свойство get» для маршрутизации?

+0

'Routings' коллекция, поэтому вы должны использовать' Add' создавать новые его Эмс. 'Routings (n)' - это доступ к элементам, которые уже созданы. –

+0

@TonyDallimore Этот синтаксис неверен для добавления в маршруты? 'code' crtg.Add ActiveSheet.Cells (i, 7) .Value 'добавить новую маршрутизацию Set mp.Routings = crtg –

+0

Вам нужен метод« Добавить »в вашем пользовательском классе. Затем в регулярном модуле вы сделаете что-то вроде 'mp.add'. Кроме того, вместо циклирования вы можете протестировать 'exist', проверив для' Error 457' при попытке сделать 'Add' в mps-коллекции. И если mp уже добавлен в mps-коллекцию; затем 'mps (key) .add'" routing " –

ответ

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 

.

Test Module:

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


Некоторые из вопросов в размещенном коде:

  • "Установить технологические карты()" и "Получить Routing()" (отсутствующий "S")
  • Получить свойство должно иметь 1 меньше параметр чем Set
  • коллекция мпс не получил бы заселена из-за If mps.count > 0 после инициализации
Смежные вопросы